; ==============================================================================
; Apple II [$D0 ROM] (341-0016) - Programmer's Aid #1 [1978]
; ==============================================================================
; Copyright (c) 1978 by Apple Computer Inc. All Rights Reserved
; ------------------------------------------------------------------------------
; Instructions are in the Programmer's Aid #1 Installation and Operating Manual
; ==============================================================================
; Analyzed (via McFadden's SourceGen) by James Davis [Last Updated: 2020-07-10]
; ==============================================================================
;
; ==============================================================================
; Programmer's Aid #1 6502 Equates:
; ==============================================================================
;
DATA EQU $00 {addr/1} ;[Normal] Test DATA ($00|$FF)
DOWNTIME EQU $00 {addr/1} ;Speaker Negative Pulse Width
R0L EQU $00 {addr/1} ;Sweet 16 Accumulator Register #0, Low
NDATA EQU $01 {addr/1} ;Inverted Test NDATA ($FF|$00)
R0H EQU $01 {addr/1} ;Sweet 16 Accumulator Register #0, High
UPTIME EQU $01 {addr/1} ;Speaker Positive Pulse Width
DURATION EQU $02 {addr/2} ;Musical Note Time-Duration Counter
R1L EQU $02 {addr/1} ;Sweet 16 Register #1, Low
TESTD EQU $02 {addr/1} ;Gallop TEST Data (see below)
R1H EQU $03 {addr/1} ;Sweet 16 Register #1, High
R2L EQU $04 {addr/1} ;Sweet 16 Register #2, Low
R2H EQU $05 {addr/1} ;Sweet 16 Register #2, High
R3L EQU $06 {addr/1} ;Sweet 16 Register #3, Low
R3H EQU $07 {addr/1} ;Sweet 16 Register #3, High
R4L EQU $08 {addr/1} ;Sweet 16 Register #4, Low
R4H EQU $09 {addr/1} ;Sweet 16 Register #4, High
R5L EQU $0A {addr/1} ;Sweet 16 Register #5, Low
INST EQU $0B {addr/3} ;3-Byte Instuction Field
R5H EQU $0B {addr/1} ;Sweet 16 Register #5, High
R6L EQU $0C {addr/1} ;Sweet 16 Register #6, Low
R6H EQU $0D {addr/1} ;Sweet 16 Register #6, High
R7L EQU $0E {addr/1} ;Sweet 16 Register #7, Low
R7H EQU $0F {addr/1} ;Sweet 16 Register #7, High
R11L EQU $16 {addr/1} ;Sweet 16 Register #11, Low
R11H EQU $17 {addr/1} ;Sweet 16 Register #11, High
SHAPEL EQU $1A {addr/1} ;Pointer to SHAPE List, Low
SHAPEH EQU $1B {addr/1} ;Pointer to SHAPE List, High
HCOLOR1 EQU $1C {addr/1} ;Running Color Mask
COUNTH EQU $1D {addr/1} ;BASIC Hi-Res Line Step, High
HBASL EQU $26 {addr/1} ;Hi-Res Graphics Base Address, Low
HBASH EQU $27 {addr/1} ;Hi-Res Graphics Base Address, High
CHKSUM EQU $2E {addr/1} ;Tape Input Accumulated Checksum
LENGTH EQU $2F {addr/1} ;Disassembler Instruction Display Length
HMASK EQU $30 {addr/1} ;Graphics On-the-Fly Color Bit Mask Safe
YSAV EQU $34 {addr/1} ;Y-Reg Safe for Monitor Command Processing
A1 EQU $3C {addr/2} ;Monitor General Purpose A1-Register
A1L EQU $3C {addr/1} ;Monitor General Purpose A1-Reg, Low
A1H EQU $3D {addr/1} ;Monitor General Purpose A1-Reg, High
A2L EQU $3E {addr/1} ;Monitor General Purpose A2-Reg, Low
A2H EQU $3F {addr/1} ;Monitor General Purpose A2-Reg, High
A4L EQU $42 {addr/1} ;Monitor General Purpose A4-Reg, Low
LOMEM EQU $4A {addr/2} ;Pointer to Start of BASIC Variables
LOMEML EQU $4A {addr/1} ;BASIC Start of Variables, Low
LOMEMH EQU $4B {addr/1} ;BASIC Start of Variables, High
HIMEM EQU $4C {addr/2} ;BASIC HIMEM Address Pointer
DXL EQU $50 {addr/1} ;Delta-X for HLIN & SHAPE, Low
DXH EQU $51 {addr/1} ;Delta-X for HLIN & SHAPE, High
DY EQU $52 {addr/1} ;Delta-Y for HLIN & SHAPE
QDRNT EQU $53 {addr/1} ;Hi-Res Graphics Rotation Quadrant (SHAPE)
EL EQU $54 {addr/1} ;Error for HLIN, Low
EH EQU $55 {addr/1} ;Error for HLIN, High
PP EQU $CA {addr/2} ;BASIC Start of Program Pointer
PPL EQU $CA {addr/1} ;BASIC Start of Program Pointer, Low
PPH EQU $CB {addr/1} ;BASIC Start of Program Pointer, High
PVL EQU $CC {addr/1} ;BASIC End of Variables Pointer, Low
PVH EQU $CD {addr/1} ;BASIC End of Variables Pointer, High
PRLEN EQU $CE {addr/2} ;BASIC Program Length
ACL EQU $CE {addr/1} ;BASIC Accumulator, Low
ACH EQU $CF {addr/1} ;BASIC Accumulator, High
XSAVE EQU $D8 {addr/1} ;BASIC X-Index Register Safe
INBUFF EQU $0200 ;Input Buffer (6502 Page 2)
TIMBRE EQU $02FD {addr/1} ;Musical Note Timbre Value (Poke 765)
TIME EQU $02FE {addr/1} ;Musical Note Time Value (Poke 766)
PITCH EQU $02FF {addr/1} ;Musical Note Pitch Value (Poke 767)
X0L EQU $0320 {addr/1} ;Prior X-Coord Safe after HLIN|HPLOT, Low
X0H EQU $0321 {addr/1} ;Prior X-Coord Safe after HLIN|HPLOT, High
Y0 EQU $0322 {addr/1} ;HLIN & HPLOT Y-Coordinate Safe
BXSAV EQU $0323 {addr/1} ;BASIC X-Reg Safe
HCOLOR EQU $0324 {addr/1} ;Color for HPLOT & HPOSN
HNDX EQU $0325 {addr/1} ;Horizontal Offset Safe
HPAG EQU $0326 {addr/1} ;Hi-Res Page (1=$20/2=$40) to Draw on
SCALE EQU $0327 {addr/1} ;SCALE for SHAPE & MOVE
SHAPXL EQU $0328 {addr/1} ;Start of SHAPE Table, Low
SHAPXH EQU $0329 {addr/1} ;Start of SHAPE Table, High
COLLSN EQU $032A {addr/1} ;Collision Count
USRADR EQU $03F8 {addr/3} ;Monitor User Command (Ctrl-Y) Vector
SPEAKER EQU $C030 {addr/1} ;Speaker Data Output Toggle Switch
TXTCLR EQU $C050 {addr/1} ;[R/W] Set Graphics Display Mode
MIXSET EQU $C053 {addr/1} ;[R/W] Set Mixed Graphics & Text Mode
HIRES EQU $C057 {addr/1} ;[R/W] Reset LoRes/Text Mode to HiRes Mode
MEMFUL EQU $E36B ;BASIC Memory Full Error
PRDEC EQU $E51B ;BASIC Print Decimal Number
RNGERR EQU $EE68 ;BASIC Range Error
LOAD EQU $F0DF ;BASIC Load from Tape Subroutine
ACADR EQU $F11E ;2-Byte Tape Read Setup
HDRSET EQU $F11E ;BASIC Set Tape Pointers to $CE,$CF
PRGSET EQU $F12C ;BASIC Set Tape Pointers for Program
SW16 EQU $F689 ;Sweet 16 Interpreter (Op-Codes follow it)
INSDS2 EQU $F88E ;Monitor Disassembler Entry Point
NXTA4 EQU $FCB4 ;Subroutine to Increment Mon A4 Register
NXTA1 EQU $FCBA ;Monitor Routine to INC (A1) then CMP (A2)
HEADR EQU $FCC9 ;Monitor Write Tape Sync Header Routine
RDBYTE EQU $FCEC ;Monitor Tape READ Routine (1-Byte|8-Bits)
RD2BIT EQU $FCFA ;Monitor Tape READ Routine (2 Transitions)
RDBIT EQU $FCFD ;Monitor Tape READ Routine (1 Transition)
CROUT EQU $FD8E ;Print Carriage Return
PRA1 EQU $FD92 ;Print CR, Hex of (A1), then Minus Sign
PRBYTE EQU $FDDA ;Print A-Reg as Two-Digit Hex Number
COUT EQU $FDED ;Print A-Reg to Output Device
READ EQU $FEFD ;Read Data from Tape (A1,A2)
READX1 EQU $FF02 ;Read Data from Tape without Header
FINISH EQU $FF26 ;Check Accumulated Checksum & Ring Bell
PRERR EQU $FF2D ;Print "ERR" & Sound Bell (Beep)
BELL EQU $FF3A ;Monitor Sound Bell Subroutine
ORG $D000
;
; ==============================================================================
; *** SourceGen needs a way to interpret Sweet 16 Operations like the following:
; [See: "SWEET16: The 6502 Dream Machine"; BYTE Magazine, Nov 1977, Pgs 150~159]
; [And: "Apple II Reference Manual (Red Book)"; §C6 Sweet 16 Listing, Pgs 96~99]
; ==============================================================================
;
; ==============================================================================
; General Sweet 16 Equates: Zero-Page Registers used for SW16 Interpreter Op's
; ==============================================================================
; R0 EQU $00 {addr/2} ;Sweet 16 Accumulator Register #0
; R0L EQU $00 {addr/1} ;Sweet 16 Accumulator Register #0, Low
; R0H EQU $01 {addr/1} ;Sweet 16 Accumulator Register #0, High
; ------------------------------------------------------------------------------
; R1 EQU $02 {addr/2} ;Sweet 16 Register #1
; R1L EQU $02 {addr/1} ;Sweet 16 Register #1, Low
; R1H EQU $03 {addr/1} ;Sweet 16 Register #1, High
; ------------------------------------------------------------------------------
; R2 EQU $04 {addr/2} ;Sweet 16 Register #2
; R2L EQU $04 {addr/1} ;Sweet 16 Register #2, Low
; R2H EQU $05 {addr/1} ;Sweet 16 Register #2, High
; ------------------------------------------------------------------------------
; R3 EQU $06 {addr/2} ;Sweet 16 Register #3
; R3L EQU $06 {addr/1} ;Sweet 16 Register #3, Low
; R3H EQU $07 {addr/1} ;Sweet 16 Register #3, High
; ------------------------------------------------------------------------------
; R4 EQU $08 {addr/2} ;Sweet 16 Register #4
; R4L EQU $08 {addr/1} ;Sweet 16 Register #4, Low
; R4H EQU $09 {addr/1} ;Sweet 16 Register #4, High
; ------------------------------------------------------------------------------
; R5 EQU $0A {addr/2} ;Sweet 16 Register #5
; R5L EQU $0A {addr/1} ;Sweet 16 Register #5, Low
; R5H EQU $0B {addr/1} ;Sweet 16 Register #5, High
; ------------------------------------------------------------------------------
; R6 EQU $0C {addr/2} ;Sweet 16 Register #6
; R6L EQU $0C {addr/1} ;Sweet 16 Register #6, Low
; R6H EQU $0D {addr/1} ;Sweet 16 Register #6, High
; ------------------------------------------------------------------------------
; R7 EQU $0E {addr/2} ;Sweet 16 Register #7
; R7L EQU $0E {addr/1} ;Sweet 16 Register #7, Low
; R7H EQU $0F {addr/1} ;Sweet 16 Register #7, High
; ------------------------------------------------------------------------------
; R8 EQU $10 {addr/2} ;Sweet 16 Register #8
; R8L EQU $10 {addr/1} ;Sweet 16 Register #8, Low
; R8H EQU $11 {addr/1} ;Sweet 16 Register #8, High
; ------------------------------------------------------------------------------
; R9 EQU $12 {addr/2} ;Sweet 16 Register #9
; R9L EQU $12 {addr/1} ;Sweet 16 Register #9, Low
; R9H EQU $13 {addr/1} ;Sweet 16 Register #9, High
; ------------------------------------------------------------------------------
; R10 EQU $14 {addr/2} ;Sweet 16 Register #10
; R10L EQU $14 {addr/1} ;Sweet 16 Register #10, Low
; R10H EQU $15 {addr/1} ;Sweet 16 Register #10, High
; ------------------------------------------------------------------------------
; R11 EQU $16 {addr/2} ;Sweet 16 Register #11
; R11L EQU $16 {addr/1} ;Sweet 16 Register #11, Low
; R11H EQU $17 {addr/1} ;Sweet 16 Register #11, High
; ------------------------------------------------------------------------------
; R12 EQU $18 {addr/2} ;Sweet 16 Register #12
; R12L EQU $18 {addr/1} ;Sweet 16 Register #12, Low
; R12H EQU $19 {addr/1} ;Sweet 16 Register #12, High
; ------------------------------------------------------------------------------
; R13 EQU $1A {addr/2} ;Sweet 16 Register #13
; R13L EQU $1A {addr/1} ;Sweet 16 Register #13, Low
; R13H EQU $1B {addr/1} ;Sweet 16 Register #13, High
; ------------------------------------------------------------------------------
; R14 EQU $1C {addr/2} ;Sweet 16 Register #14
; R14L EQU $1C {addr/1} ;Sweet 16 Register #14, Low
; R14H EQU $1D {addr/1} ;Sweet 16 Register #14, High
; ------------------------------------------------------------------------------
; R15 EQU $1E {addr/2} ;Sweet 16 Register #15
; R15L EQU $1E {addr/1} ;Sweet 16 Register #15, Low
; R15H EQU $1F {addr/1} ;Sweet 16 Register #15, High
; ==============================================================================
;
;
; ==============================================================================
; Apple II [$D0 ROM] (341-0016) - Programmer's Aid #1 [1978]
; ------------------------------------------------------------------------------
; Part 1 [$D000~$D3FF]: High-Resolution Graphics Subroutines
; by Steve Wozniak [WOZ], 1977-09-13;
; Copyright (c) 1978 by Apple Computer Inc. All Rights Reserved
; ------------------------------------------------------------------------------
; Instructions are in the Programmer's Aid #1 Installation and Operating Manual
; ==============================================================================
; Analyzed (via McFadden's SourceGen) by James Davis [Last Updated: 2020-07-10]
; ==============================================================================
;
; ==============================================================================
; High Resolution Graphics Inits [ROM Version $D000 to $D3FF]
; ==============================================================================
;
D000: A9 20 SETHRL LDA #$20 ;Initialize Hi-Res Page 1 =($2000~$3FFF):
D002: 8D 26 03 STA HPAG ;Set Hi-Res Screen Area =(32 Memory Pages)
D005: AD 57 C0 LDA HIRES ;Set Hi-Res Display Mode ...
D008: AD 53 C0 LDA MIXSET ; with Text at Bottom
D00B: AD 50 C0 LDA TXTCLR ;Set Graphics Display Mode
D00E: A9 00 HCLR LDA #0
D010: 85 1C BKGND0 STA HCOLOR1 ;Set for Black Background
D012: AD 26 03 BKGND LDA HPAG
D015: 85 1B STA SHAPEH ;Init Hi-Res Screen Memory ...
D017: A0 00 LDY #0 ; for Current Page, normally
D019: 84 1A STY SHAPEL ; $2000~$3FFF or $4000~$5FFF
D01B: A5 1C BKGND1 LDA HCOLOR1
D01D: 91 1A STA (SHAPEL),Y
D01F: 20 A2 D0 JSR CSHFT2 ;(SHAPEL,H) will specify ...
D022: C8 INY ; 32 Separate Pages ...
D023: D0 F6 BNE BKGND1 ; throughout the Init
D025: E6 1B INC SHAPEH
D027: A5 1B LDA SHAPEH
D029: 29 1F AND #%00011111 ;Test for Done
D02B: D0 EE BNE BKGND1
D02D: 60 RTS ;Return to Caller
; ==============================================================================
; Hi-Res Graphics Position & Plot Subroutines
; ==============================================================================
;
D02E: 8D 22 03 HPOSN STA Y0 ;Enter with Y in A-Reg, ...
D031: 8E 20 03 STX X0L ; XL in X-Reg, & ...
D034: 8C 21 03 STY X0H ; XH in Y-Reg, for ...
D037: 48 PHA
D038: 29 C0 AND #%11000000
D03A: 85 26 STA HBASL ; Y-Coordinate = 00ABCDEF
D03C: 4A LSR A ;Calculates Base Address ...
D03D: 4A LSR A ; in HBASL,HBASH for ...
D03E: 05 26 ORA HBASL ; Accessing Screen Memory ...
D040: 85 26 STA HBASL ; via (HBASL),Y Addressing Mode
D042: 68 PLA
D043: 85 27 STA HBASH
D045: 0A ASL A ;Calculates ...
D046: 0A ASL A ; HBASH = PPPFGHCD, ...
D047: 0A ASL A ; HBASL = EABAB000, ...
D048: 26 27 ROL HBASH
D04A: 0A ASL A ; Where PPP=001 for $2000~$3FFF ...
D04B: 26 27 ROL HBASH ; Screen Memory Range & ...
D04D: 0A ASL A ; PPP1010 for $4000~$7FFF ...
D04E: 66 26 ROR HBASL ; (Given Y-Coordinate=ABCDEFGH)
D050: A5 27 LDA HBASH
D052: 29 1F AND #%00011111
D054: 0D 26 03 ORA HPAG
D057: 85 27 STA HBASH
D059: 8A TXA ;Divide X0 by 7 for ...
D05A: C0 00 CPY #0 ; Index from Base Address ...
D05C: F0 05 BEQ HPOSN2 ; (Quotient) & Bit ...
D05E: A0 23 LDY #$23 ; within Screen Memory Byte ...
D060: 69 04 ADC #4 ; (Mask Specified by Remainder) ...
D062: C8 HPOSN1 INY
D063: E9 07 HPOSN2 SBC #7 ; Subtract Out Sevens
D065: B0 FB BCS HPOSN1
D067: 8C 25 03 STY HNDX ;Works for X0 from ...
D06A: AA TAX ; 0 to 279, Low-Order ...
D06B: BD EA D0 LDA LRUD3,X ; Byte in X-Reg, ...
D06E: 85 30 STA HMASK ; High in Y-Reg on Entry
D070: 98 TYA
D071: 4A LSR A ;If on Odd Byte (Carry Set), ...
D072: AD 24 03 LDA HCOLOR ; Then Rotate HCOLOR One ...
D075: 85 1C HPOSN3 STA HCOLOR1 ; Bit for 180 Degree Shift ...
D077: B0 29 BCS CSHFT2 ; Prior to Copying to HCOLOR1
D079: 60 RTS ;Return to Caller
D07A: 20 2E D0 HPLOT JSR HPOSN
D07D: A5 1C HPLOT1 LDA HCOLOR1 ;Calculate Bit Position in HBASL,H, ...
D07F: 51 26 EOR (HBASL),Y ; HNDX, & HMASK from ...
D081: 25 30 AND HMASK ; Y-Coordinate in A-Reg, ...
D083: 51 26 EOR (HBASL),Y ; X-Coordinate in X,Y-Regs
D085: 91 26 STA (HBASL),Y ;For any 'L' Bits of HMASK ...
D087: 60 RTS ; Substitute Corresponding Bit of HCOLOR1
; ==============================================================================
; Hi-Res Graphics L,R,U,D Subroutines
; ==============================================================================
;
D088: 10 24 LFTRT BPL RIGHT ;Use Sign for Left/Right Select
D08A: A5 30 LEFT LDA HMASK
D08C: 4A LSR A ;Shift Low-Order ...
D08D: B0 05 BCS LEFT1 ; 7 Bits of HMASK ...
D08F: 49 C0 EOR #%11000000 ; One Bit to Lsb
D091: 85 30 LR1 STA HMASK
D093: 60 RTS ;Return to Caller
D094: 88 LEFT1 DEY ;Decrement Horizontal Index
D095: 10 02 BPL LEFT2
D097: A0 27 LDY #39 ;Wrap Around Screen
D099: A9 C0 LEFT2 LDA #%11000000 ;New HMASK, Righthost ...
D09B: 85 30 NEWNDX STA HMASK ; Dot of Byte
D09D: 8C 25 03 STY HNDX ;Update Horizontal Index
D0A0: A5 1C CSHIFT LDA HCOLOR1
D0A2: 0A CSHFT2 ASL A ;Rotate Low-Order ...
D0A3: C9 C0 CMP #%11000000 ; 7 Bits of HCOLOR1 ...
D0A5: 10 06 BPL RTS1 ; One Bit Position
D0A7: A5 1C LDA HCOLOR1
D0A9: 49 7F EOR #%01111111 ;ZXYXYXYX -> ZYXYXYXY
D0AB: 85 1C STA HCOLOR1
D0AD: 60 RTS1 RTS ;Return to Caller
D0AE: A5 30 RIGHT LDA HMASK
D0B0: 0A ASL A ;Shift Low-Order ...
D0B1: 49 80 EOR #%10000000 ; 7 Bits of HMASK ...
D0B3: 30 DC BMI LR1 ; One Bit to Msb
D0B5: A9 81 LDA #$81
D0B7: C8 INY ;Next Byte
D0B8: C0 28 CPY #$28
D0BA: 90 DF BCC NEWNDX
D0BC: A0 00 LDY #0 ;Wrap Around Screen If >279
D0BE: B0 DB BCS NEWNDX ;Always Taken
; ==============================================================================
; L,R,U,D Subroutines
; ==============================================================================
;
D0C0: 18 LRUDX1 CLC ;No 90 Degree Rotation (XOR)
D0C1: A5 51 LRUDX LDA DXH
D0C3: 29 04 AND #%00000100 ;If Bit2=0 then No Plot
D0C5: F0 27 BEQ LRUD4
D0C7: A9 7F LDA #%01111111 ;For XOR into Screen Memory
D0C9: 25 30 AND HMASK
D0CB: 31 26 AND (HBASL),Y ;Screen Bit Set?
D0CD: D0 1B BNE LRUD3
D0CF: EE 2A 03 INC COLLSN
D0D2: A9 7F LDA #%01111111
D0D4: 25 30 AND HMASK
D0D6: 10 12 BPL LRUD3 ;Always Taken
;
D0D8: 18 LRUD1 CLC ;No 90 Degree Rotation
D0D9: A5 51 LRUD2 LDA DXH
D0DB: 29 04 AND #%00000100 ;If Bit2=0 then No Plot
D0DD: F0 0F BEQ LRUD4
D0DF: B1 26 LDA (HBASL),Y
D0E1: 45 1C EOR HCOLOR1 ;Set Hi-Res Screen Bit ...
D0E3: 25 30 AND HMASK ; to Corresponding HCOLOR1
D0E5: D0 03 BNE LRUD3 ;If Bit of Screen Changes ...
D0E7: EE 2A 03 INC COLLSN ; then Increment Collision Detect
D0EA: 51 26 LRUD3 EOR (HBASL),Y
D0EC: 91 26 STA (HBASL),Y
D0EE: A5 51 LRUD4 LDA DXH ;Add Quadrant to Specified Vector; ...
D0F0: 65 53 ADC QDRNT ; & Move Left, Right, Up, or Down, ...
D0F2: 29 03 AND #%00000011 ;<-[EQ3-1=(3)]; based on Sign & Carry
D0F4: C9 02 EQ3 CMP #%00000010
D0F6: 6A ROR A
D0F7: B0 8F LRUD BCS LFTRT
D0F9: 30 30 UPDWN BMI DOWN4 ;Sign for Up/Down Select
D0FB: 18 UP CLC
D0FC: A5 27 LDA HBASH ;Calculate Base Address ...
D0FE: 2C EA D1 BIT EQ1C ; (Address of Leftmost Byte) ...
D101: D0 22 BNE UP4 ; for Next Line Up ...
D103: 06 26 ASL HBASL ; in (HBASL,HBASH) ...
D105: B0 1A BCS UP2 ; with 192-Line Wraparound
D107: 2C F3 D0 BIT EQ3-1
D10A: F0 05 BEQ UP1
D10C: 69 1F ADC #$1F ;**** Bit Map ****
D10E: 38 SEC
D10F: B0 12 BCS UP3 ;Always Taken; For Row = ABCDEFGH, ...
D111: 69 23 UP1 ADC #$23
D113: 48 PHA
D114: A5 26 LDA HBASL ; HBASL = EABAB000
D116: 69 B0 ADC #$B0 ; HBASH = PPPFGHCD
D118: B0 02 BCS UP5
D11A: 69 F0 ADC #$F0 ;Where PPP=001 for Primary ...
D11C: 85 26 UP5 STA HBASL ; Hi-Res Page ($2000-$3FFF)
D11E: 68 PLA
D11F: B0 02 BCS UP3
D121: 69 1F UP2 ADC #$1F
D123: 66 26 UP3 ROR HBASL
D125: 69 FC UP4 ADC #$FC
D127: 85 27 UPDWN1 STA HBASH
D129: 60 RTS ;Return to Caller
D12A: 18 DOWN0 CLC
D12B: A5 27 DOWN4 LDA HBASH ;Calculate BASE Address for NEXT LINE ...
D12D: 69 04 ADC #4 ;<-[EQ4-1=(4)]; Down to (HBASL,HBASH) ...
D12F: 2C EA D1 EQ4 BIT EQ1C
D132: D0 F3 BNE UPDWN1
D134: 06 26 ASL HBASL ; with 192-Line Wraparound
D136: 90 19 BCC DOWN1
D138: 69 E0 ADC #$E0
D13A: 18 CLC
D13B: 2C 2E D1 BIT EQ4-1
D13E: F0 13 BEQ DOWN2
D140: A5 26 LDA HBASL
D142: 69 50 ADC #%01010000
D144: 49 F0 EOR #%11110000
D146: F0 02 BEQ DOWN3
D148: 49 F0 EOR #%11110000
D14A: 85 26 DOWN3 STA HBASL
D14C: AD 26 03 LDA HPAG
D14F: 90 02 BCC DOWN2
D151: 69 E0 DOWN1 ADC #$E0
D153: 66 26 DOWN2 ROR HBASL
D155: 90 D0 BCC UPDWN1
;
; ==============================================================================
; Hi-Res Graphics Line Draw Subroutines
; ==============================================================================
;
D157: 48 HLINRL PHA
D158: A9 00 LDA #0 ;Set (XOL,XOH) & ...
D15A: 8D 20 03 STA X0L ; Y0 to Zero for ...
D15D: 8D 21 03 STA X0H ; Relative Line Draw ...
D160: 8D 22 03 STA Y0 ; Y0 (DX,DY)
D163: 68 PLA
D164: 48 HLIN PHA ;On Entry ...
D165: 38 SEC ; XL: A-Reg
D166: ED 20 03 SBC X0L ; XH: X-Reg
D169: 48 PHA ; Y: Y-REG
D16A: 8A TXA
D16B: ED 21 03 SBC X0H
D16E: 85 53 STA QDRNT ;Calculate ABS(X-X0) ...
D170: B0 0A BCS HLIN2 ; in (DXL,DXH)
D172: 68 PLA
D173: 49 FF EOR #%11111111 ;X-Direction to Sign Bit ...
D175: 69 01 ADC #%00000001 ; of Quadrant ...
D177: 48 PHA ; 0=Right (DX Positive), ...
D178: A9 00 LDA #0 ; 1=Left (DX Negative)
D17A: E5 53 SBC QDRNT
D17C: 85 51 HLIN2 STA DXH
D17E: 85 55 STA EH ;Init (EL,EH) to ...
D180: 68 PLA ; ABS(X-X0)
D181: 85 50 STA DXL
D183: 85 54 STA EL
D185: 68 PLA
D186: 8D 20 03 STA X0L
D189: 8E 21 03 STX X0H
D18C: 98 TYA
D18D: 18 CLC
D18E: ED 22 03 SBC Y0 ;Calculate -ABS(Y-0)-1 ...
D191: 90 04 BCC HLIN3 ; in DY
D193: 49 FF EOR #%11111111
D195: 69 FE ADC #%11111110
D197: 85 52 HLIN3 STA DY ;Rotate Y-Direction into ...
D199: 8C 22 03 STY Y0 ; Quadrant Sign Bit ...
D19C: 66 53 ROR QDRNT ; (0=Up, 1=Down)
D19E: 38 SEC
D19F: E5 50 SBC DXL ;Init (COUNTL,COUNTH) ...
D1A1: AA TAX ; to -(DELTX+DELTY+1)
D1A2: A9 FF LDA #$FF
D1A4: E5 51 SBC DXH
D1A6: 85 1D STA COUNTH
D1A8: AC 25 03 LDY HNDX ;Horizontal Index
D1AB: B0 05 BCS MOVEX2 ;Always Taken
;
D1AD: 0A MOVEX ASL A ;Move in X-Direction
D1AE: 20 88 D0 JSR LFTRT ;Use Quadrant Bit 6 for Left/Right Select
D1B1: 38 SEC
D1B2: A5 54 MOVEX2 LDA EL ;Assume Carry Set
D1B4: 65 52 ADC DY ;(EL,EH)-DELTY to (EL,EH)
D1B6: 85 54 STA EL ;Note: DY is (-DELTY)-1
D1B8: A5 55 LDA EH ;Carry Clear if (EL,EH) ...
D1BA: E9 00 SBC #0 ; goes Negative
D1BC: 85 55 HCOUNT STA EH
D1BE: B1 26 LDA (HBASL),Y ;Screen Byte
D1C0: 45 1C EOR HCOLOR1 ;Plot Dot of HCOLOR1
D1C2: 25 30 AND HMASK ;Current Bit Mask
D1C4: 51 26 EOR (HBASL),Y
D1C6: 91 26 STA (HBASL),Y
D1C8: E8 INX ;Done (DELTX+DELTY)
D1C9: D0 04 BNE HLIN4 ;Dots?
D1CB: E6 1D INC COUNTH
D1CD: F0 6B BEQ RTS2 ;Yes, Return to Caller
;
D1CF: A5 53 HLIN4 LDA QDRNT ;For Direction Test ...
D1D1: B0 DA BCS MOVEX ; If Carry Set, (EL,EH) Positive, ...
D1D3: 20 F9 D0 JSR UPDWN ; If Clear, Negative, Move in Y-Direction
D1D6: 18 CLC
D1D7: A5 54 LDA EL ;(EL,EH)+DELTX ...
D1D9: 65 50 ADC DXL ; to (EL,EH)
D1DB: 85 54 STA EL
D1DD: A5 55 LDA EH ;Carry Set if (EL,EH) goes Positive
D1DF: 65 51 ADC DXH
D1E1: 50 D9 BVC HCOUNT ;Always Taken
;
D1E3: 81 MSKTBL HEX 81 ;<-[Bit-7] Leftmost Bit of Byte
D1E4: 82 84 88 HEX 828488
D1E7: 90 A0 HEX 90A0
D1E9: C0 HEX C0 ;<-[Bit-1 is NOT] Rightmost Bit of Byte
D1EA: 1C EQ1C HEX 1C ;<-[Bit-0 is] Rightmost Bit of Byte [!]
D1EB: FF FE FA F4 COS HEX FFFEFAF4
D1EF: EC E1 D4 C5 HEX ECE1D4C5
D1F3: B4 A1 8D 78 HEX B4A18D78
D1F7: 61 49 31 18 HEX 61493118
D1FB: FF HEX FF
;
; ==============================================================================
; Hi-Res Graphics Coordinate Restore Subroutine
; ==============================================================================
;
D1FC: A5 26 HFIND LDA HBASL
D1FE: 0A ASL A ;Converts Base Address ...
D1FF: A5 27 LDA HBASH ; to Y-Coordinate
D201: 29 03 AND #%00000011
D203: 2A ROL A ;For HBASL = EABAB000 ...
D204: 05 26 ORA HBASL ; & HBASH = PPPFGHCD, ...
D206: 0A ASL A
D207: 0A ASL A ;Generate ...
D208: 0A ASL A ; Y-Coordinate = ABCDEFGH
D209: 8D 22 03 STA Y0
D20C: A5 27 LDA HBASH ;(PPP=Screen Page, ...
D20E: 4A LSR A ; Normally 001 for ...
D20F: 4A LSR A ; $2000-$3FFF ...
D210: 29 07 AND #%00000111 ; Hi-Res Screen)
D212: 0D 22 03 ORA Y0
D215: 8D 22 03 STA Y0 ;Converts HNDX (Index ...
D218: AD 25 03 LDA HNDX ; from Base Address) ...
D21B: 0A ASL A ; & HMASK (Bit ...
D21C: 6D 25 03 ADC HNDX ; Mask) to X-Coordinate ...
D21F: 0A ASL A ; in (X0L,X0H) ...
D220: AA TAX ; (Range $0~$133)
D221: CA DEX
D222: A5 30 LDA HMASK
D224: 29 7F AND #%01111111
D226: E8 HFIND1 INX
D227: 4A LSR A
D228: D0 FC BNE HFIND1
D22A: 8D 21 03 STA X0H
D22D: 8A TXA
D22E: 18 CLC
D22F: 6D 25 03 ADC HNDX ;Calculate HNDX*7 + LOG (Base 2) HMASK
D232: 90 03 BCC HFIND2
D234: EE 21 03 INC X0H
D237: 8D 20 03 HFIND2 STA X0L
D23A: 60 RTS2 RTS ;Return to Caller
; ==============================================================================
; Hi-Res Graphics Shape Draw Subroutine
; ==============================================================================
; Shape Draw
; R = 0 to 63
; Scale Factor used (1=Normal)
; ==============================================================================
;
D23B: 86 1A DRAW STX SHAPEL ;Draw Definition ...
D23D: 84 1B STY SHAPEH ; Pointer
D23F: AA DRAW1 TAX
D240: 4A LSR A ;Rotation ($0~$3F)
D241: 4A LSR A
D242: 4A LSR A ;Quadrant 0=Up, 1=Right, 2=Down, 3=Left
D243: 4A LSR A
D244: 85 53 STA QDRNT
D246: 8A TXA
D247: 29 0F AND #%00001111
D249: AA TAX
D24A: BC EB D1 LDY COS,X ;Save COS & SIN ...
D24D: 84 50 STY DXL ; Values in DXL & DY
D24F: 49 0F EOR #%00001111
D251: AA TAX
D252: BC EC D1 LDY COS+1,X
D255: C8 INY
D256: 84 52 STY DY
D258: AC 25 03 DRAW2 LDY HNDX ;Byte Index From Hi-Res Base Address
D25B: A2 00 LDX #0
D25D: 8E 2A 03 STX COLLSN ;Clear Collision Count
D260: A1 1A LDA (SHAPEL,X) ;1st Shape Definition Byte
D262: 85 51 DRAW3 STA DXH
D264: A2 80 LDX #$80
D266: 86 54 STX EL ;EL,EH for Fractional L,R,U,D Vectors
D268: 86 55 STX EH
D26A: AE 27 03 LDX SCALE ;Scale Factor
D26D: A5 54 DRAW4 LDA EL
D26F: 38 SEC ;If Fractional COS Overflow then ...
D270: 65 50 ADC DXL ; Move in Specified Vector Direction
D272: 85 54 STA EL
D274: 90 04 BCC DRAW5
D276: 20 D8 D0 JSR LRUD1
D279: 18 CLC
D27A: A5 55 DRAW5 LDA EH ;If Fractional SIN Overflow, Move in ...
D27C: 65 52 ADC DY ; Specified Vector Direction +90 Degrees
D27E: 85 55 STA EH
D280: 90 03 BCC DRAW6
D282: 20 D9 D0 JSR LRUD2
D285: CA DRAW6 DEX ;Loop on Scale Factor
D286: D0 E5 BNE DRAW4
D288: A5 51 LDA DXH
D28A: 4A LSR A ;Next 3-Bit Vector of Shape Definition
D28B: 4A LSR A
D28C: 4A LSR A
D28D: D0 D3 BNE DRAW3 ;Not Done this Byte
D28F: E6 1A INC SHAPEL
D291: D0 02 BNE DRAW7 ;Next Byte of Shape Definition
D293: E6 1B INC SHAPEH
D295: A1 1A DRAW7 LDA (SHAPEL,X)
D297: D0 C9 BNE DRAW3 ;Done If Zero
D299: 60 RTS ;Return to Caller
; ==============================================================================
; Hi-Res Graphics Shape XOR Subroutine
; ==============================================================================
; XOR Shape into Screen
;
; Rotation = 0 to 3 (Quadrant Only)
; Scale is Used
; ==============================================================================
;
D29A: 86 1A XDRAW STX SHAPEL ;Shape Definition Pointer
D29C: 84 1B STY SHAPEH
D29E: AA XDRAW1 TAX
D29F: 4A LSR A ;Rotation ($0-$3F)
D2A0: 4A LSR A
D2A1: 4A LSR A ;Quadrant: 0=Up, 1=Right, 2=Down, 3=Left
D2A2: 4A LSR A
D2A3: 85 53 STA QDRNT
D2A5: 8A TXA
D2A6: 29 0F AND #%00001111
D2A8: AA TAX
D2A9: BC EB D1 LDY COS,X ;Save COS & SIN Values in DXL & DY
D2AC: 84 50 STY DXL
D2AE: 49 0F EOR #%00001111
D2B0: AA TAX
D2B1: BC EC D1 LDY COS+1,X
D2B4: C8 INY
D2B5: 84 52 STY DY
D2B7: AC 25 03 XDRAW2 LDY HNDX ;Index from Hi-Res Base Address
D2BA: A2 00 LDX #0
D2BC: 8E 2A 03 STX COLLSN ;Clear Collision Detect
D2BF: A1 1A LDA (SHAPEL,X) ;1St Shape Definition Byte
D2C1: 85 51 XDRAW3 STA DXH
D2C3: A2 80 LDX #$80
D2C5: 86 54 STX EL ;EL,EH for Fractional L,R,U,D, Vectors
D2C7: 86 55 STX EH
D2C9: AE 27 03 LDX SCALE ;Scale Factor
D2CC: A5 54 XDRAW4 LDA EL
D2CE: 38 SEC ;If Fractional COS Overflow then ...
D2CF: 65 50 ADC DXL ; Move in Specified Vector Direction
D2D1: 85 54 STA EL
D2D3: 90 04 BCC XDRAW5
D2D5: 20 C0 D0 JSR LRUDX1
D2D8: 18 CLC
D2D9: A5 55 XDRAW5 LDA EH ;If Fractional SIN Overflow, Move in ...
D2DB: 65 52 ADC DY ; Specified Vector Direction +90 Degrees
D2DD: 85 55 STA EH
D2DF: 90 03 BCC XDRAW6
D2E1: 20 D9 D0 JSR LRUD2
D2E4: CA XDRAW6 DEX ;Loop on Scale Factor
D2E5: D0 E5 BNE XDRAW4
D2E7: A5 51 LDA DXH
D2E9: 4A LSR A ;Next 3-Bit Vector of Shape Definition
D2EA: 4A LSR A
D2EB: 4A LSR A
D2EC: D0 D3 BNE XDRAW3
D2EE: E6 1A INC SHAPEL
D2F0: D0 02 BNE XDRAW7 ;Next Byte of Shape Definition
D2F2: E6 1B INC SHAPEH
D2F4: A1 1A XDRAW7 LDA (SHAPEL,X)
D2F6: D0 C9 BNE XDRAW3 ;Done If Zero
D2F8: 60 RTS ;Return to Caller
; ==============================================================================
; Entry Points from Apple-II BASIC
; ==============================================================================
;
D2F9: 20 90 D3 BPOSN JSR PCOLR ;BASIC Position Call; Get Color from BASIC
D2FC: 8D 24 03 STA HCOLOR
D2FF: 20 AF D3 JSR GETY0 ;Get Y0 from BASIC
D302: 48 PHA
D303: 20 9A D3 JSR GETX0 ;Get X0 from BASIC
D306: 68 PLA
D307: 20 2E D0 JSR HPOSN
D30A: AE 23 03 LDX BXSAV
D30D: 60 RTS ;Return to Caller
D30E: 20 F9 D2 BPLOT JSR BPOSN ;BASIC Plot Call
D311: 4C 7D D0 JMP HPLOT1
D314: AD 25 03 BLIN1 LDA HNDX
D317: 4A LSR A ;Set HCOLOR1 from BASIC Variable Color
D318: 20 90 D3 JSR PCOLR
D31B: 20 75 D0 JSR HPOSN3
D31E: 20 9A D3 BLINE JSR GETX0 ;BASIC Line Call, Get X0 from BASIC
D321: 8A TXA
D322: 48 PHA
D323: 98 TYA
D324: AA TAX
D325: 20 AF D3 JSR GETY0 ;Get Y0 from BASIC
D328: A8 TAY
D329: 68 PLA
D32A: 20 64 D1 JSR HLIN
D32D: AE 23 03 LDX BXSAV
D330: 60 RTS ;Return to Caller
D331: 20 90 D3 BGND JSR PCOLR ;BASIC Background Call
D334: 4C 10 D0 JMP BKGND0
; ==============================================================================
; Draw Routines
; ==============================================================================
;
D337: 20 F9 D2 BDRAW1 JSR BPOSN
D33A: 20 51 D3 BDRAW JSR BDRAWX ;DRAW CALL from BASIC
D33D: 20 3B D2 JSR DRAW
D340: AE 23 03 LDX BXSAV
D343: 60 RTS ;Return to Caller
D344: 20 F9 D2 BXDRW1 JSR BPOSN
D347: 20 51 D3 BXDRAW JSR BDRAWX ;XOR-DRAW CALL from BASIC
D34A: 20 9A D2 JSR XDRAW
D34D: AE 23 03 LDX BXSAV
D350: 60 RTS ;Return to Caller
D351: 8E 23 03 BDRAWX STX BXSAV ;Save for BASIC
D354: A0 32 LDY #$32
D356: 20 92 D3 JSR PBYTE ;Scale from BASIC
D359: 8D 27 03 STA SCALE
D35C: A0 28 LDY #$28
D35E: 20 92 D3 JSR PBYTE ;Rotation from BASIC
D361: 48 PHA ;Save on Stack
D362: AD 28 03 LDA SHAPXL
D365: 85 1A STA SHAPEL ;Start of Shape Table
D367: AD 29 03 LDA SHAPXH
D36A: 85 1B STA SHAPEH
D36C: A0 20 LDY #$20
D36E: 20 92 D3 JSR PBYTE ;Shape from BASIC
D371: F0 39 BEQ RERR1
D373: A2 00 LDX #0
D375: C1 1A CMP (SHAPEL,X) ;Is it > Number of Shapes?
D377: F0 02 BEQ BDRWX1
D379: B0 31 BCS RERR1 ;Yes, Range Error
D37B: 0A BDRWX1 ASL A
D37C: 90 03 BCC BDRWX2
D37E: E6 1B INC SHAPEH
D380: 18 CLC
D381: A8 BDRWX2 TAY ;No, Multiply by 2
D382: B1 1A LDA (SHAPEL),Y
D384: 65 1A ADC SHAPEL
D386: AA TAX ;Add 2-Byte Index ...
D387: C8 INY ; to Shape Table ...
D388: B1 1A LDA (SHAPEL),Y ; Start Address ...
D38A: 6D 29 03 ADC SHAPXH ; [(X,Y)={Low,High}]
D38D: A8 TAY
D38E: 68 PLA ;Rotation from Stack
D38F: 60 RTS ;Return to Caller
; ==============================================================================
; BASIC Parameter Fetch Subroutines
; ==============================================================================
;
D390: A0 16 PCOLR LDY #$16
D392: B1 4A PBYTE LDA (LOMEML),Y
D394: D0 16 BNE RERR1 ;Get BASIC Parameter
D396: 88 DEY ;(Error If >255)
D397: B1 4A LDA (LOMEML),Y
D399: 60 RTSB RTS ;Return to Caller
D39A: 8E 23 03 GETX0 STX BXSAV ;Save for BASIC
D39D: A0 05 LDY #5
D39F: B1 4A LDA (LOMEML),Y ;X0 Low-Order Byte
D3A1: AA TAX
D3A2: C8 INY
D3A3: B1 4A LDA (LOMEML),Y ;X0 High-Order Byte
D3A5: A8 TAY
D3A6: E0 18 CPX #24
D3A8: E9 01 SBC #1 ;Range Error If >279
D3AA: 90 ED BCC RTSB ;Return to Caller
D3AC: 4C 68 EE RERR1 JMP RNGERR
D3AF: A0 0D GETY0 LDY #13 ;Offset to Y0 from LOMEM
D3B1: 20 92 D3 JSR PBYTE ;Get BASIC Parameter Y0
D3B4: C9 C0 CMP #$C0 ;(Error If >191)
D3B6: B0 F4 BCS RERR1
D3B8: 60 RTS ;Return to Caller
; ==============================================================================
; Shape Tape Load Subroutine
; ==============================================================================
;
D3B9: 8E 23 03 SHLOAD STX BXSAV ;Save for BASIC
D3BC: 20 1E F1 JSR ACADR ;Read 2-Byte Length into ...
D3BF: 20 FD FE JSR READ ; BASIC Accumulator
D3C2: A9 00 LDA #0 ;Start of Shape Table is $0800
D3C4: 85 3C STA A1L
D3C6: 8D 28 03 STA SHAPXL
D3C9: 18 CLC
D3CA: 65 CE ADC ACL
D3CC: A8 TAY
D3CD: A9 08 LDA #8 ;High Byte of Shape Table Pointer
D3CF: 85 3D STA A1H
D3D1: 8D 29 03 STA SHAPXH
D3D4: 65 CF ADC ACH
D3D6: B0 25 BCS MFULL1 ;Not Enough Memory
D3D8: C4 CA CPY PPL
D3DA: 48 PHA
D3DB: E5 CB SBC PPH
D3DD: 68 PLA
D3DE: B0 1D BCS MFULL1
D3E0: 84 3E STY A2L
D3E2: 85 3F STA A2H
D3E4: C8 INY
D3E5: D0 02 BNE SHLOD1
D3E7: 69 01 ADC #1
D3E9: 84 4A SHLOD1 STY LOMEML
D3EB: 85 4B STA LOMEMH
D3ED: 84 CC STY PVL
D3EF: 85 CD STA PVH
D3F1: 20 FA FC JSR RD2BIT
D3F4: A9 03 LDA #3 ;.5 Second Header
D3F6: 20 02 FF JSR READX1
D3F9: AE 23 03 LDX BXSAV
D3FC: 60 RTS ;Return to Caller
D3FD: 4C 6B E3 MFULL1 JMP MEMFUL ;BASIC Memory Full Error
;
; ==============================================================================
; Apple II [$D0 ROM] (341-0016) - Programmer's Aid #1 [1978]
; ------------------------------------------------------------------------------
; Part 2 [$D400~$D4D4]: Apple II BASIC Renumber / Append Subroutines
; Version Two by Steve Wozniak [WOZ], 1978-04-12;
; Copyright (c) 1978 by Apple Computer Inc. All Rights Reserved
; ------------------------------------------------------------------------------
; Instructions are in the Programmer's Aid #1 Installation and Operating Manual
; ==============================================================================
; Analyzed (via McFadden's SourceGen) by James Davis [Last Updated: 2020-07-10]
; ==============================================================================
;
; ****************************************
; * *
; * RENUMBER *
; * >CLR *
; * >START= *
; * >STEP= *
; * >CALL -10531 *
; * =($D6DD) *
; * *
; * OPTIONAL *
; * >FROM= *
; * >TO= *
; * >CALL -10521 *
; * =($D6E7) *
; * *
; * USE RENX ENTRY *
; * FOR RENUMBER ALL *
; * *
; ****************************************
;
; These Entry Points (in box above), -10531 = $D6DD & -10521 = $D6E7, are
; located elsewhere, in another section of binary code. I'll need to get
; "A Round Tuit" (at a later date), if you want to see it (done/analyzed).
; Done, See: Apple II Programmers Aid 1.2.5.$D692~$D716 - Entry Points.
;
; ==============================================================================
; *** SourceGen needs a way to interpret Sweet 16 Operations like the following:
; [See: "SWEET16: The 6502 Dream Machine"; BYTE Magazine, Nov 1977, Pgs 150~159]
; [And: "Apple II Reference Manual (Red Book)"; §C6 Sweet 16 Listing, Pgs 96~99]
; ==============================================================================
;
; ==============================================================================
; Renumber/Append 6502 Equates:
; ==============================================================================
; A2 Locations used here (within SW16 Code Blocks, but not listed/decoded above)
; ------------------------------------------------------------------------------
; HIMEM EQU $4C {addr/2} ;BASIC HIMEM Pointer, Low/High
; PPL EQU $CA {addr/2} ;BASIC Program Pointer, Low/High
; PVL EQU $CC {addr/2} ;BASIC Variable Pointer, Low/High
; ==============================================================================
;
; ==============================================================================
; Renumber/Append Sweet 16 Equates: SW16 Registers & Locations used here
; ==============================================================================
; ACC EQU $00 {addr/2} ;R0: Sweet 16 Accumulator
; NEWLOW EQU $01 {addr/1} ;R0H: New Initial Line Number (LNO)
; NEWINCR EQU $02 {addr/1} ;R1L: New LNO Increment (INCR) Value
; LNLO EQU $03 {addr/1} ;R1H: Low LNO of RENUM Range
; LNHI EQU $04 {addr/1} ;R2L: High LNO of RENUM Range
; TBLSTRT EQU $05 {addr/1} ;R2H: LNO Table Start
; TBLINDX1 EQU $06 {addr/1} ;R3L: Pass 1 LNO Table Index
; TBLND EQU $06 {addr/1} ;R3L: Pass 2 LNO Table End
; TBLIM EQU $07 {addr/1} ;R3H: LNO Table Limit
; PRGNDX2 EQU $07 {addr/1} ;R3H: Pass 2 Program Index
; SCR8 EQU $08 {addr/1} ;R4L: Scratch Register
; HMEM EQU $08 {addr/1} ;R4L: HIMEM (End of Program)
; SCR9 EQU $09 {addr/1} ;R4H: Scratch Register
; PRGNDX EQU $09 {addr/1} ;R4H: Pass 1 Program Index
; CHR9 EQU $09 {addr/1} ;R4H: ASCII "0" (Constant Safe)
; PRGNDX1 EQU $0A {addr/1} ;R5L: Pass 1 Program Index 1
; CHRA EQU $0A {addr/1} ;R5L: ASCII "@" (Constant Safe)
; NEWLN EQU $0B {addr/1} ;R5H: Next "New LNO" Assignment
; TBLNDX2 EQU $0B {addr/1} ;R5H: LNO Table Index for Update
; STRCON EQU $0B {addr/1} ;R5H: BASIC String Constant Token
; NEWLN1 EQU $0C {addr/1} ;R6L: Prior "New LNO" Assignment
; MODE EQU $0C {addr/1} ;R6L: LNO Mode Constant
; REM EQU $0C {addr/1} ;R6L: BASIC REM Token
; SCRC EQU $0C {addr/1} ;R6L: Scratch Register for Append
; OLDLN EQU $0D {addr/1} ;R6H: Old LNO for Update
; CPRREG EQU $0D {addr/1} ;R6H: Compare (CPR) Register [Not R13 !!!]
; THEN EQU $0D {addr/1} ;R6H: BASIC THEN Token
; LIST EQU $0D {addr/1} ;R6H: BASIC LIST Token
; DEL EQU $0D {addr/1} ;R6H: BASIC DEL Token
; ==============================================================================
;
;
; ==============================================================================
; Apple II BASIC Renumber Subroutine - Pass 1
; ==============================================================================
;
; ------------------------------------------------------------------------------
; ;Optional Range Entry; Use to Renumber All
D400: 20 89 F6 RENX JSR SW16 ;Sweet 16 Interpreter (Op-Codes follow)...
; ------------------------------------------------------------------------------
D403: B0 DFB $B0 ;SUB ACC ;R0:
D404: 33 DFB $33 ;ST LNLO ;Set LNLO=0
D405: 34 DFB $34 ;ST LNHI ;Set LNHI=0
D406: F4 DFB $F4 ;DCR LNHI ;Reduce LNHI (from 0 to -1)
D407: 00 DFB $00 ;RTN ;[Return to 6502 Mode]
; ==============================================================================
; Apple II BASIC Renumber Subroutine
; ==============================================================================
;
; ------------------------------------------------------------------------------
; ;Both BASIC Entry Pt. Calls will Jump Here
D408: 20 89 F6 RENUM JSR SW16 ;Sweet 16 Interpreter (Op-Codes follow)...
; ------------------------------------------------------------------------------
D40B: 18 4C 00 HEX 184C00 ;SET HMEM,HIMEM
D40E: 68 DFB $68 ;LDD @HMEM
D40F: 38 DFB $38 ;ST HMEM
D410: 19 CE 00 RNUM3 HEX 19CE00 ;SET SCR9,PVL+2
D413: C9 DFB $C9 ;POPD @SCR9 ;BASIC Var Pnt to ...
D414: 35 DFB $35 ;ST TBLSTRT ;<- TBLSTRT & ...
D415: 36 DFB $36 ;ST TBLNDX1 ;<- TBLNDX1
D416: 21 DFB $21 ;LD NEWLOW ;Copy NEWLOW (Intl) to ...
D417: 3B DFB $3B ;ST NEWLN ;<- NEWLN & ...
D418: 3C DFB $3C ;ST NEWLN1 ;<- NEWLN1
D419: C9 DFB $C9 ;POPD @SCR9 ;BASIC Program Pntr to ...
D41A: 37 DFB $37 ;ST TBLIM ;<- TBLIM & ...
D41B: 39 DFB $39 ;ST PRGNDX ;<- PRGNDX
D41C: 29 PASS1 DFB $29 ;LD PRGNDX
D41D: D8 DFB $D8 ;CPR HMEM ;If PRGNDX >= HMEM, ...
D41E: 03 46 DDB $0346 ;BC PASS2 ;Then Done with Pass 1
D420: 3A DFB $3A ;ST PRGNDX1
D421: 26 DFB $26 ;LD TBLNDX1
D422: E0 DFB $E0 ;INR ACC ;If < 2 Bytes avail in ...
D423: D7 DFB $D7 ;CPR TBLIM ;LNO Table, then Return ...
D424: 03 38 DDB $0338 ;BC MERR ;with "MEM FULL" Message
D426: 4A DFB $4A ;LD @PRGNDX1
D427: A9 DFB $A9 ;ADD PRGNDX ;Add Length to Prog Index
D428: 39 DFB $39 ;ST PRGNDX
D429: 6A DFB $6A ;LDD @PRGNDX1 ;Line Number
D42A: D3 DFB $D3 ;CPR LNLO ;If < LNLO, Goto P1C
D42B: 02 2A DDB $022A ;BNC P1B
D42D: D4 DFB $D4 ;CPR LNHI ;If > LNHI, Goto P1C
D42E: 02 02 DDB $0202 ;BNC P1A
D430: 07 30 DDB $0730 ;BNZ P1C
D432: 76 P1A DFB $76 ;STD @TBLNDX1 ;Add to LNO Table
D433: 00 DFB $00 ;RTN ;[Return to 6502 Mode]
; ----------------------------------- ;Print 'Old Line #' "->" 'New Line #'
; ; [SW16: (R0,R11)] in Decimal:
;
; ------------------------ ;**** 6502 Code Block Start ****
D434: A5 01 LDA R0H ;Get Sweet 16 Register #0, High
D436: A6 00 LDX R0L ;Get Sweet 16 Register #0, Low
D438: 20 1B E5 JSR PRDEC ;Print Decimal Number
D43B: A9 AD LDA #'-' | $80 ;Get a Dash Character
D43D: 20 ED FD JSR COUT ;Print A-Reg to Output Device
D440: A9 BE LDA #'>' | $80 ;Get a Greater Than Sign
D442: 20 ED FD JSR COUT ;Print A-Reg to Output Device
D445: A5 17 LDA R11H ;Get Sweet 16 Register #11, High
D447: A6 16 LDX R11L ;Get Sweet 16 Register #11, Low
D449: 20 1B E5 JSR PRDEC ;Print Decimal Number
D44C: 20 8E FD JSR CROUT ;Print a Carriage Return
; ------------------------ ;**** 6502 Code Block End ****
;
; ------------------------------------------------------------------------------
D44F: 20 8C F6 JSR SW16+3 ;Sweet 16 Interpreter (Op-Codes follow)...
; ------------------------------------------------------------------------------
D452: 2B DFB $2B ;LD NEWLN
D453: 3C DFB $3C ;ST NEWLN1 ;Copy NEWLN to NEWLN1 & ...
D454: A2 DFB $A2 ;ADD NEWINCR ;Increase NEWLN by NEWINCR
D455: 3B DFB $3B ;ST NEWLN
D456: 0D DFB $0D ;HEX 0D ;'NUL' (Will Skip Next Op)
D457: D1 P1B DFB $D1 ;CPR NEWLOW ;If Low LNO < New Low, ...
; ; ; ; ;then "RANGE ERR"
D458: 02 C2 DDB $02C2 ;BNC PASS1 ;Loop if Not
; ----------------------------------- ;------------- ;Else, Print Err Message:
D45A: 00 RERR DFB $00 ;RTN ;[Return to 6502 Mode]
D45B: 4C 68 EE JMP RNGERR ;6502 Code: BASIC Range Error
; ----------------------------------- ;------------- ;Print Err Message:
D45E: 00 MERR DFB $00 ;RTN ;[Return to 6502 Mode]
D45F: 4C 6B E3 JMP MEMFUL ;6502 Code: BASIC Memory Full Error
; ----------------------------------- ;------------- ;[Continue SW16 Process]:
D462: EC P1C DFB $EC ;INR NEWLN1 ;If Hi LNO <= Current NEWLN
D463: DC DFB $DC ;CPR NEWLN1 ;then "RANGE ERR" ...
D464: 02 F4 DDB $02F4 ;BNC RERR ;Go Print Err Message
;
; ==============================================================================
; Apple II BASIC Renumber / Append Subroutine - Pass 2
; ==============================================================================
;
D466: 19 B0 00 PASS2 HEX 19B000 ;CHR9,$00B0 ;SET (Constant)=(ASCII "0")
D469: 1A C0 00 HEX 1AC000 ;CHRA,$00C0 ;SET (Constant)=(ASCII "@")
; ------------------------------------------------------------------------------
; *** NOTE: $C0 is an "@" (AT sign)!--Not an "A" character (as shown in the
; listing in the "Programmer's Aid #1 Installation & Operating Manual")!
; ------------------------------------------------------------------------------
D46C: 27 P2A DFB $27 ;LD PRGNDX2
D46D: D8 DFB $D8 ;CPR HMEM ;If PRGNDX2 = HIMEM, ...
D46E: 03 63 DDB $0363 ;BC DONE ;then Pass 2 is Done
D470: E7 DFB $E7 ;INR PRGNDX2 ;Skip Length Byte
D471: 67 DFB $67 ;LDD @PRGNDX2 ;Line Number
D472: 3D UPDATE DFB $3D ;ST OLDLN ;Save Old LNO
D473: 25 DFB $25 ;LD TBLSTRT
D474: 3B DFB $3B ;ST TBLNDX2 ;Init LNO Table Index
D475: 21 DFB $21 ;LD NEWLOW ;Init NEWLN to NEWLOW
D476: 1C DFB $1C ;HEX 1C ;(Will Skip Next Op)
D477: 2C UD2 DFB $2C ;LD NEWLN1
D478: A2 DFB $A2 ;ADD NEWINCR ;Add INCR to NEWLN1
D479: 3C DFB $3C ;ST NEWLN1
D47A: 2B DFB $2B ;LD TBLNDX2 ;If LNO TBL IDX = TBLND ...
D47B: B6 DFB $B6 ;SUB TBLND ;then Done Scanning LNO TBL
D47C: 03 07 DDB $0307 ;BC UD3
D47E: 6B DFB $6B ;LDD @TBLNDX2 ;Next LNO from Table
D47F: BD DFB $BD ;SUB OLDLN ;Loop to UD2 If Not = OLDLN
D480: 07 F5 DDB $07F5 ;BNZ UD2
D482: C7 DFB $C7 ;POPD @PRGNDX2 ;Replace Old LNO with ...
D483: 2C DFB $2C ;LD NEWLN1 ;Corresponding New Line
D484: 77 DFB $77 ;STD @PRGNDX2
D485: 1B 28 00 UD3 HEX 1B2800 ;SET STRCON,$0028 ;STR CON Token
D488: 1C DFB $1C ;HEX 1C ;(Skips Next Two Ops)
D489: 67 GOTCON DFB $67 ;LDD @PRGNDX2
D48A: FC DFB $FC ;DCR MODE ;If MODE = 0 Update LNO Ref
D48B: 08 E5 DDB $08E5 ;BM1 UPDATE
D48D: 47 ITEM DFB $47 ;LD @PRGNDX2 ;BASIC Token
D48E: D9 DFB $D9 ;CPR CHR9
D48F: 02 09 DDB $0209 ;BNC CHKTOK ;Check Token for Special
D491: DA DFB $DA ;CPR CHRA ;If >= "0" & < "@" ...
D492: 02 F5 DDB $02F5 ;BNC GOTCON ;Skip Const or Update
D494: F7 SPKASC DFB $F7 ;DCR PRGNDX2
D495: 67 DFB $67 ;LDD @PRONDX2 ;Skip all Neg Bytes of ...
D496: 05 FC DDB $05FC ;BM SKPASC ;STR CON, REM or NAME
D498: F7 DFB $F7 ;DCR PRGNDX2
D499: 47 DFB $47 ;LD @PRGNDX2
D49A: DB CHKTOC DFB $DB ;CPR STRCON ;STR CON Token?
D49B: 06 F7 DDB $06F7 ;BZ SKPASC ;Yes, Skip Subseguent Bytes
D49D: 1C 5D 00 HEX 1C5D00 ;SET REM,$005D
D4A0: DC DFB $DC ;CPR REM ;REM Token?
D4A1: 06 F1 DDB $06F1 ;B2 SKPASC ;Yes, Skip Subseguent Line
D4A3: 08 13 DDB $0813 ;BM1 CONTST ;GOSUB, Look for Line #
D4A5: FD DFB $FD ;DCR R13
D4A6: FD DFB $FD ;DCR R13 ;(Token $5F is GOTO)
D4A7: 06 0F DDB $060F ;BZ CONTST
D4A9: 1D 24 00 HEX 1D2400 ;SET THEN,$0024
D4AC: DD DFB $DD ;CPR THEN
D4AD: 06 09 DDB $0609 ;BZ CONTST ;'THEN' LNO, Look for LNO
D4AF: F0 DFB $F0 ;DCR ACC
D4B0: 06 BA DDB $06BA ;BZ P2A ;EOL (Token 01)?
D4B2: 1D 74 00 HEX 1D7400 ;SET LIST,$0074
D4B5: BD DFB $BD ;SUB LIST ;Set Mode if "LIST"|"LIST,"
D4B6: 09 01 DDB $0901 ;BNM1 CONTS2 ;(Tokens $74, $75)
D4B8: B0 CONTST DFB $B0 ;SUB ACC ;Clear Mode for LNO
D4B9: 3C CONTS2 DFB $3C ;ST MODE ;Update Check
D4BA: 01 D1 DDB $01D1 ;BR ITEM
; ==============================================================================
; Apple II BASIC Append Subroutine
; ==============================================================================
;
; ------------------------------------------------------------------------------
; BASIC: 1st LOAD (from Tape) 2nd Integer BASIC Program with high line numbers;
; then CALL -11076 to LOAD & Append 1st Program with low line numbers
; ------------------------------------------------------------------------------
D4BC: 20 89 F6 APPEND JSR SW16 ;Sweet 16 Interpreter (Op-Codes follow)...
; ------------------------------------------------------------------------------
D4BF: 1C 4E 00 HEX 1C4E00 ;SET SCRC,HIMEM+2
D4C2: CC DFB $CC ;POPD @SCRC ;Save HIMEM
D4C3: 38 DFB $38 ;ST HMEM
D4C4: 19 CA 00 HEX 19CA00 ;SET SCR9,PPL
D4C7: 69 DFB $69 ;LDD @SCR9
D4C8: 7C DFB $7C ;STD @SCRC ;Set HIMEM to Preserve Prog
D4C9: 00 DFB $00 ;RTN ;[Return to 6502 Mode]
D4CA: 20 DF F0 JSR LOAD ;6502 Code: Load from Tape
;
; ------------------------------------------------------------------------------
; BASIC: CALL -11059 to Recover 2nd Program when Append fails w/ Mem Full Error!
; ------------------------------------------------------------------------------
D4CD: 20 89 F6 RECOVER JSR SW16 ;Sweet 16 Interpreter (Op-Codes follow)...
; ------------------------------------------------------------------------------
D4D0: CC DFB $CC ;POPD @SCRC ;Restore HIMEM to Show ...
D4D1: 28 DFB $28 ;LD HMEM ;Both Programs (Old & New)
D4D2: 7C DFB $7C ;STD @SCRC
D4D3: 00 :DONE DFB $00 ;RTN ;[Return to 6502 Mode]
;
D4D4: 60 RTS ;6502 Code: Return to Caller
;
; ==============================================================================
; Apple II [$D0 ROM] (341-0016) - Programmer's Aid #1 [1978]
; ------------------------------------------------------------------------------
; Part 3 [$D4D5~$D52D]: 6502 Relocation Subroutine
; by Steve Wozniak [WOZ], 1977-11-10;
; Copyright (c) 1978 by Apple Computer Inc. All Rights Reserved
; ------------------------------------------------------------------------------
; Instructions are in the Programmer's Aid #1 Installation and Operating Manual
; ==============================================================================
; Analyzed (via McFadden's SourceGen) by James Davis [Last Updated: 2020-07-10]
; ==============================================================================
;
; ==============================================================================
; Set Monitor User Command (Ctrl-Y) Vector to Relocater Routine Location:
; ==============================================================================
;
; *** Typing "D4D5G <Return>" at Monitor Prompt (*) init's the Relocater Program
;
; ----------------------------------- ;Setup Mon User Cmd (Ctrl-Y) Location:
D4D5: A9 DC SETRLCYV LDA #<RELOC ;Get Relocater Routine Address, Low
D4D7: A0 D4 LDY #>RELOC ;Get Relocater Routine Address, High
D4D9: 4C B0 D5 JMP SETUSRADR ;Setup Mon User Cmd (Ctrl-Y) Vector
; ------------------------------------------------------------------------------
; The Monitor User Command (Ctrl-Y) Vector Setup Routine, SETUSRADR (set user
; address), is shared by the Relocater, Tape Verify, & RAM Test Routines, and is
; located further below, between the Tape Verify & RAM Test Routines, at $D5B0.
; ==============================================================================
;
;
; ==============================================================================
; 6502 Relocation Subroutine [For use via Apple II Monitor (at Star {*} Prompt)]
; ==============================================================================
; 1. Define Blocks: *A4<A1.A2 ^Y (^Y is Ctrl-Y)
; ------------------------------------------------------------------------------
; 2. First Segment: *A4<A1.A2 ^Y (If Code)
; *A4<A1.A2M (If Move)
; ------------------------------------------------------------------------------
; 3. Subsequent Segments: *.A2 ^Y (If Code)
; *.A2M (If Move)
; ==============================================================================
;
D4DC: A4 34 RELOC LDY YSAV ;Get Monitor Command Processing Pointer
D4DE: B9 00 02 LDA INBUFF,Y ;Get Monitor Command from Input Buffer
D4E1: C9 AA CMP #'*' | $80 ;Assure we are at the Monitor Prompt
D4E3: D0 0C BNE RELOC2 ;Branch if Not at the Monitor Prompt
; ;Else, Initialize Relocation Pointers:
D4E5: E6 34 INC YSAV ;Advance Command Processing Pointer
D4E7: A2 07 LDX #7 ;Prepare to Copy 8 Bytes ...
D4E9: B5 3C INIT LDA A1L,X ;From: Monitor General Purpose Registers
D4EB: 95 02 STA R1L,X ;To: Sweet 16 Interpreter (ZP) Registers
D4ED: CA DEX ;Reduce Byte-Count Index-Pointer
D4EE: 10 F9 BPL INIT ;Loop until all Bytes have been Copied
D4F0: 60 RTS ;Then Return to Caller
D4F1: A0 02 RELOC2 LDY #2 ;Prepare to Copy 3 Bytes ...
D4F3: B1 3C GETINS LDA (A1L),Y ;From: A1 Address Pointer [(Indirect),Y]
D4F5: 99 0B 00 STA INST,Y ;To: 3-Byte Instuction Field [Abs,Y]
D4F8: 88 DEY ;Reduce Byte-Count Index-Pointer
D4F9: 10 F8 BPL GETINS ;Loop until all Bytes have been Copied
; ;Compute Instruction Length from Op-Code:
D4FB: 20 8E F8 JSR INSDS2 ;Monitor Disassembler Entry Point
D4FE: A6 2F LDX LENGTH ;Disassembler Instruction Display Length
; ;^[Sets X=# of Bytes: 1, 2, or 3]
D500: CA DEX ;Reduce Byte-Count Index-Pointer
; ;^[Now, # of Bytes is X+1: X= 0, 1, or 2]
D501: D0 0C BNE TRANSLATE ;If Not Zero, Interpret Sweet 16 Op-Codes
D503: A5 0B LDA INST ;Get Instuction from 3-Byte Field
D505: 29 0D AND #%00001101 ;Weed Out Non-Zero-Page ...
D507: F0 14 BEQ STINST ; 2-Byte Immediate Operations
D509: 29 08 AND #%00001000 ;If Zero-Page Address, ...
D50B: D0 10 BNE STINST ; Then Clear High Byte
D50D: 85 0D STA INST+2 ;3-Byte Instuction Field
D50F: 20 89 F6 TRANSLATE JSR SW16 ;Sweet 16 Interpreter (Op-Codes follow)...
; ==============================================================================
; *** SourceGen needs a way to interpret Sweet 16 Operations like the following:
; [See: "SWEET16: The 6502 Dream Machine"; BYTE Magazine, Nov 1977, Pgs 150~159]
; [And: "Apple II Reference Manual (Red Book)"; §C6 Sweet 16 Listing, Pgs 96~99]
; ==============================================================================
; Sweet 16 Equates: Zero-Page Locations used here for Sweet 16 Interpreter Op's
; ==============================================================================
; FRMBEG EQU $01 {addr/1} ;SW16/R0H: Beginning of Source Block
; FRMEND EQU $02 {addr/2} ;SW16/R1L: End of Source Block {Low/High}*
; TOBEG EQU $04 {addr/2} ;SW16/R2L: Beginning of Destination Block*
; ADR EQU $06 {addr/2} ;SW16/R3L: Address Part of Instuction
; ==============================================================================
; TRANSLATE JSR SW16 ;Sweet 16 Interpreter (Op-Codes follow)...
; ^ XLATE ^ ------------------------------------- ;If Address of Zero Page
D512: 22 DFB $22 ;LD FRMEND ;or Absolute Address is in
D513: D6 DFB $D6 ;CPR ADR ;Source (FRM) Block then
D514: 02 06 DDB $0206 ;BNC SW16RT ;Substitute:
D516: 26 DFB $26 ;LD ADR ;(Address Part of Instuction)
D517: B1 DFB $B1 ;SUB FRMBEG ;-(Source Start Address)
D518: 02 02 DDB $0202 ;BNC SW16RT ;[Exit: Branch if No Carry]
D51A: A4 DFB $A4 ;ADD TOBEG ;+(Destination Start Address)
D51B: 36 DFB $36 ;ST ADR ;(Address Part of Instuction)
D51C: 00 :SW16RT DFB $00 ;RTN ;[Return to 6502 Mode]
; ==============================================================================
;
D51D: A2 00 STINST LDX #0 ;Clear X-Index; Prep to Copy LENGTH Bytes
D51F: B5 0B STINS2 LDA INST,X ;From: 3-Byte Instuction Field [Abs,X]
D521: 91 42 STA (A4L),Y ;To: A4 Address Pointer [(Indirect),Y]
D523: E8 INX ;Advance X-Index
D524: 20 B4 FC JSR NXTA4 ;Subroutine to Increment Mon A4 Register
D527: C6 2F DEC LENGTH ;Disassembler Instruction Display Length
D529: 10 F4 BPL STINS2 ;Loop until all Bytes have been Copied
D52B: 90 C4 BCC RELOC2 ;Loop until Relocation is Finished
D52D: 60 RTS ;Return to Caller
;
; ==============================================================================
; Apple II [$D0 ROM] (341-0016) - Programmer's Aid #1 [1978]
; ------------------------------------------------------------------------------
; Part 4 [$D52E~$D5BB]: Tape Verify Routine by Steve Wozniak [WOZ], 1978-01;
; Copyright (c) 1978 by Apple Computer Inc. All Rights Reserved
; ------------------------------------------------------------------------------
; Instructions are in the Programmer's Aid #1 Installation and Operating Manual
; ==============================================================================
; Analyzed (via McFadden's SourceGen) by James Davis [Last Updated: 2020-07-10]
; ==============================================================================
;
; ==============================================================================
; Set Monitor User Command (Ctrl-Y) Vector to Tape Verify Routine Location:
; ==============================================================================
;
; *** Typing "D52EG <Return>" at Monitor Prompt (*) init's Tape Verify Program
;
; ----------------------------------- ;Setup Mon User Cmd (Ctrl-Y) Location:
D52E: A9 54 SETTVCYV LDA #<TAPEVFY ;Get Tape Verify Routine Address, Low
D530: A0 D5 LDY #>TAPEVFY ;Get Tape Verify Routine Address, High
D532: 4C B0 D5 JMP SETUSRADR ;Setup Mon User Cmd (Ctrl-Y) Vector
; ------------------------------------------------------------------------------
; The Monitor User Command (Ctrl-Y) Vector Setup Routine, SETUSRADR (set user
; address), is shared by the Relocater, Tape Verify, & RAM Test Routines, and is
; located further below, between the Tape Verify & RAM Test Routines, at $D5B0.
; ==============================================================================
;
; ==============================================================================
; Tape Verify BASIC Routine:
; ==============================================================================
;
; ----------------------------------- ;BASIC Verify S/R Entry Pt.: Call -10955
; ;(to verify a program just saved on Tape)
D535: 86 D8 VFYBSC STX XSAVE ;Preserve X-Index Register for BASIC
; ;Calculate Program Length, Put into PRLEN:
D537: 38 SEC ;Prep for Subtract w/o Borrow [A-Data-!C]
D538: A2 FF LDX #$FF ;Prep X-Index: Adrs+1, X=255=-1 & X=256=0
D53A: B5 4D GETLEN LDA HIMEM+1,X ;GET HIMEM Address, Low 1st & High 2nd It
D53C: F5 CB SBC PP+1,X ;Subtract Program Start Address, Low/High
D53E: 95 CF STA PRLEN+1,X ;Set Program Length, Low 1st & High 2nd
D540: E8 INX ;Advance X-Index: X=255=-1 -> X=256=0
D541: F0 F7 BEQ GETLEN ;Loop to Do High Addresses, 2nd Iteration
D543: 20 1E F1 JSR HDRSET ;Set Tape Pointers to ...
D546: 20 54 D5 JSR TAPEVFY ;Verify Header on Tape
D549: A2 01 LDX #1 ;Prep for PRGSET
D54B: 20 2C F1 JSR PRGSET ;Set Tape Pointers to ...
D54E: 20 54 D5 JSR TAPEVFY ;Verify Program on Tape
D551: A6 D8 LDX XSAVE ;Restore X-Reg for BASIC
D553: 60 RTS ;Return to Caller
; ==============================================================================
; Tape Verify RAM Image (A1,A2):
; ==============================================================================
;
D554: 20 FA FC TAPEVFY JSR RD2BIT ;Monitor Tape READ Routine (2 Transitions)
D557: A9 16 LDA #$16 ;Set Synchronization Header Length
D559: 20 C9 FC JSR HEADR ;Synchronize on Tape Header
D55C: 85 2E STA CHKSUM ;Initialize Tape Accumulated Checksum
D55E: 20 FA FC JSR RD2BIT ;Monitor Tape READ Routine (2 Transitions)
; ----------------------------------- ;Read a Bit from Tape (Loop):
D561: A0 24 VRFY2 LDY #$24 ;Set Count for RD2BIT/RDBIT Sampling
; ;^[Gets Reduced Until Voltage Transitions]
; ;^[(Used to Set Carry Flag for a One-Bit)]
D563: 20 FD FC JSR RDBIT ;Monitor Tape READ Routine (1 Transition)
D566: B0 F9 BCS VRFY2 ;Loop if RD2BIT/RDBIT Read a One-Bit
D568: 20 FD FC JSR RDBIT ;Monitor Tape READ Routine (1 Transition)
D56B: A0 3B LDY #$3B ;Set Count for RD2BIT/RDBIT Sampling
; ;^[Gets Reduced Until Voltage Transitions]
; ;^[2 Transitions/Bit; 16 Transitions/Byte]
; ----------------------------------- ;Read a Byte from Tape (Loop):
D56D: 20 EC FC VRFY3 JSR RDBYTE ;Monitor Tape READ Routine (1-Byte|8-Bits)
D570: F0 0E BEQ EXTDEL ;RDBYTE Returns (X=0)->(Z=1); Always Taken
;
; ----------------------------------- ;Accumulator contains Byte Read from Tape
D572: 45 2E VFYLOOP EOR CHKSUM ;Update Tape Accumulated Checksum
D574: 85 2E STA CHKSUM ;Set New Tape Accumulated Checksum
D576: 20 BA FC JSR NXTA1 ;Increment A1; Sets Carry Flag if A1>A2
D579: A0 34 LDY #$34 ;Set Count for RD2BIT/RDBIT Sampling
; ;^[Gets Reduced Until Voltage Transitions]
; ;^[2 Transitions/Bit; 16 Transitions/Byte]
; ;^[One < used in Read for an Extra 12 (?)]
D57B: 90 F0 BCC VRFY3 ;Loop Until A1>A2
D57D: 4C 26 FF JMP FINISH ;Verify Checksum & Beep; Returns to Caller
; ----------------------------------- ;Extra Delay to Equalize Timing:
D580: EA EXTDEL NOP ;Delay 2 Machine Cycles
D581: EA NOP ;Delay 2 Machine Cycles More
D582: EA NOP ;Delay 2 Machine Cycles (+12 usec total)
; ----------------------------------- ;Accumulator contains Byte Read from Tape
D583: C1 3C CMP (A1,X) ;Is Byte in Mem Same as Byte from Tape?
D585: F0 EB BEQ VFYLOOP ;Loop if Bytes Match
; =================================== ;Else, Handle Error:
D587: 48 PHA ;Push/Save Wrong Byte from Tape
D588: 20 2D FF JSR PRERR ;Print "ERR" & Sound Bell (Beep)
D58B: 20 92 FD JSR PRA1 ;Print CR, (A1:Address), then Minus Sign
D58E: B1 3C LDA (A1),Y ;Get Byte from Memory at (A1:Address),Y=0
D590: 20 DA FD JSR PRBYTE ;Print A-Reg as Two-Digit Hex Number
D593: A9 A0 LDA #' ' | $80 ;Get a Blank/Space Character
D595: 20 ED FD JSR COUT ;Print A-Reg to Output Device
D598: A9 A8 LDA #'(' | $80 ;Get an Open-Parenthesis Character
D59A: 20 ED FD JSR COUT ;Print A-Reg to Output Device
D59D: 68 PLA ;Pull/Retrieve Bad Byte Saved from Tape
D59E: 20 DA FD JSR PRBYTE ;Print A-Reg as Two-Digit Hex Number
D5A1: A9 A9 LDA #')' | $80 ;Get a Close-Parenthesis Character
D5A3: 20 ED FD JSR COUT ;Print A-Reg to Output Device
D5A6: A9 8D LDA #$8D ;Get High ASCII Ctrl-M: Carriage Return
D5A8: 4C ED FD JMP COUT ;Print A-Reg to Output; Returns to Caller
; =================================== ;Extra Repeated Code (Unused/Filler):
D5AB: A9 8D XCROUT LDA #$8D ;Get High ASCII Ctrl-M: Carriage Return
D5AD: 4C ED FD JMP COUT ;Print A-Reg to Output; Returns to Caller
;
; ==============================================================================
; Apple II [$D0 ROM] (341-0016) - Programmer's Aid #1 [1978]
; ------------------------------------------------------------------------------
; Part 4.5 [$D5B0~$D5BB]: Monitor User Command (Ctrl-Y) Vector Setup Routine
; Copyright (c) 1978 by Apple Computer Inc. All Rights Reserved
; ------------------------------------------------------------------------------
; Instructions are in the Programmer's Aid #1 Installation and Operating Manual
; ==============================================================================
; Analyzed (via McFadden's SourceGen) by James Davis [Last Updated: 2020-07-10]
; ==============================================================================
;
; ==============================================================================
; Monitor User Command (Ctrl-Y) Vector Setup Routine:
; ==============================================================================
; Shared by: RAM Test, Relocater, & Tape Verify Routines
; ------------------------------------------------------------------------------
;
; ----------------------------------- ;Setup Mon User Cmd (Ctrl-Y) Vector:
D5B0: 8D F9 03 SETUSRADR STA USRADR+1 ;Preset User Address, Low
D5B3: 8C FA 03 STY USRADR+2 ;Preset User Address, High
D5B6: A9 4C LDA #$4C ;Get JMP OpCode
D5B8: 8D F8 03 STA USRADR ;Preset to JMP OpCode
D5BB: 60 RTS ;Return to Caller
;
; ==============================================================================
; Apple II [$D0 ROM] (341-0016) - Programmer's Aid #1 [1978]
; ------------------------------------------------------------------------------
; Part 5 [$D5B0~$D691]: RAM Test Routine by Steve Wozniak [WOZ], 1977-06;
; Copyright (c) 1978 by Apple Computer Inc. All Rights Reserved
; ------------------------------------------------------------------------------
; Instructions are in the Programmer's Aid #1 Installation and Operating Manual
; ==============================================================================
; Analyzed (via McFadden's SourceGen) by James Davis [Last Updated: 2020-07-10]
; ==============================================================================
;
; ==============================================================================
; Set Monitor User Command (Ctrl-Y) Vector to RAM Test Routine Location:
; ==============================================================================
;
; *** Typing "D5BCG <Return>" at Monitor Prompt (*) init's the RAM Test Program
;
; ----------------------------------- ;Setup Mon User Cmd (Ctrl-Y) Location:
D5BC: A9 C3 SETRTCYV LDA #<RAMTEST ;Get RAM Test Routine Address, Low
D5BE: A0 D5 LDY #>RAMTEST ;Get RAM Test Routine Address, High
D5C0: 4C B0 D5 JMP SETUSRADR ;Setup Mon User Cmd (Ctrl-Y) Vector
; ==============================================================================
; RAM Test Routine:
; ==============================================================================
;
; *** Typing "Adrs.Pgs Ctrl-Y <Return>" at the Monitor Prompt (*) tests RAM,
; starting at the hexadecimal address (Adrs) given, and continuing through the
; number of hexadecimal pages (Pgs) given. The starting address (Adrs) low byte
; must be typed in, but its value (<> $00) is ignored in this routine, so RAM
; Tests always start & end at a 6502 page boundary. Pgs must be <= Adrs page.
; See additional instructions in the "Programmer's Aid #1 Installation and
; Operating Manual" (Ch.6 RAM Test, Pages 29~34).
;
; ----------------------------------- ;Main (Ctrl-Y) Entry Point:
D5C3: A9 00 RAMTEST LDA #0 ;Set [Normal] Test DATA = Zero
D5C5: 20 D0 D5 JSR RAMTEST0 ;Test RAM with [Normal] Test DATA
D5C8: A9 FF LDA #$FF ;Set [Normal] Test DATA = ($FF|255|-1)
D5CA: 20 D0 D5 JSR RAMTEST0 ;Test RAM with [Normal] Test DATA
D5CD: 4C 3A FF JMP BELL ;Sound Bell (Beep); Returns to Caller
; ----------------------------------- ;Initialize DATA & Inverse NDATA Safes:
D5D0: 85 00 RAMTEST0 STA DATA ;Save Test DATA ($00|$FF)
D5D2: 49 FF EOR #%11111111 ;Invert Test DATA ($00|$FF)->($FF|$00)
D5D4: 85 01 STA NDATA ;Save Inverted Test NDATA ($FF|$00)
; ----------------------------------- ;Initialize Pointers:
D5D6: A5 3D LDA A1H ;Get Start of Test Block Address, High
D5D8: 85 07 STA R3H ;Init Pointer: Aux-Register #3, High
D5DA: 85 09 STA R4H ;Init Pointer: Aux-Register #4, High
D5DC: 85 0B STA R5H ;Init Pointer: Aux-Register #5, High
D5DE: A0 00 LDY #0 ;Get Start of Test Block Address, Low
; ;^[A1L is ignored, so RAM Tests always ]
; ; [start & end at a 6502 Page Boundary!]
D5E0: 84 06 STY R3L ;Init Pointer: Aux-Register #3, Low
D5E2: 84 08 STY R4L ;Init Pointer: Aux-Register #4, Low
D5E4: 84 0A STY R5L ;Init Pointer: Aux-Register #5, Low
D5E6: A6 3E LDX A2L ;Get Length (Pages) [from Monitor]
; ----------------------------------- ;Set Entire Test Block (Bytes)=(DATA):
D5E8: A5 00 LDA DATA ;Retrieve Test DATA ($00|$FF)
D5EA: 91 08 RAMTEST1 STA (R4L),Y ;Store (DATA) in each Byte of Test Block
D5EC: C8 INY ;Advance Byte Pointer [0..255]
D5ED: D0 FB BNE RAMTEST1 ;Loop until 256 Memory Bytes have been Set
D5EF: E6 09 INC R4H ;Advance Page Pointer
D5F1: CA DEX ;Reduce Page Counter (Length)
D5F2: D0 F6 BNE RAMTEST1 ;Loop until all Pages are Done
; ----------------------------------- ;Verify Entire Test Block (Bytes)=(DATA):
D5F4: A6 3E LDX A2L ;Get Length (Pages) [from Monitor]
D5F6: B1 06 RAMTEST2 LDA (R3L),Y ;Retrieve Memory Byte from Test Block
D5F8: C5 00 CMP DATA ;Assure it is Correct [(Memory) = (DATA)]
D5FA: F0 13 BEQ RAMTEST3 ;Branch if it is Correct [(A) = (DATA)]
; ----------------------------------- ;Else, Memory is Incorrect; Handle Error;
; ;Print Bad Memory's Adrs & Bit-Error Data:
D5FC: 48 PHA ;Preserve Bad (Memory Failure) Data
; ;Print Memory Address:
D5FD: A5 07 LDA R3H ;Get Start of Test Block Address, High
D5FF: 20 DA FD JSR PRBYTE ;Print A-Reg as Two-Digit Hex Number
D602: 98 TYA ;Get Byte Pointer
D603: 20 8A D6 JSR RTPRBYSP ;Print (A):[as Two-Digit Hex #] & a Space
; ;Print Expected Data & Bad Memory Data:
D606: A5 00 LDA DATA ;Retrieve Test DATA ($00|$FF)
D608: 20 8A D6 JSR RTPRBYSP ;Print (A):[as Two-Digit Hex #] & a Space
D60B: 68 PLA ;Retrieve Bad (Memory Failure) Data
; ------------------------------------------------------------------------------
D60C: 20 92 D6 JSR RTBADMEM ;Print Bad Memory Chip's Location: The ...
; ;Row & Column on Apple II Motherboards
; ------------------------------------------------------------------------------
; The line above is code from an actual PA1 ROM. It is changed from that in
; the "Programmer's Aid #1 Installation and Operating Manual" "RAMTEST" listing
; (pages 84~86). [$D60C:2092D6 JSR $D692 versus 207FD6 JSR $D67F, respectively]
; ------------------------------------------------------------------------------
; [versus] JSR RTPRBYCR ;Print (A):[##], Error + Beep, Space + CR;
; ------------------------------------------------------------------------------
;
; ----------------------------------- ;Continue Test Block Verification:
D60F: C8 RAMTEST3 INY ;Advance Byte Pointer [0..255]
D610: D0 E4 BNE RAMTEST2 ;Loop until 256 Bytes have been Verified
D612: E6 07 INC R3H ;Advance Byte Pointer [0..255]
D614: CA DEX ;Reduce Page Counter (Length)
D615: D0 DF BNE RAMTEST2 ;Loop until all Pages are Done
; ----------------------------------- ;Set Entire Test Block (Bytes)=(NDATA) &
; ;Gallop Through Memory Bytes [Test Loops]:
; ;^[Testing Memory Test Bytes for Changes ]
; ;^[when Neighboring Address Bytes are Set]
D617: A6 3E LDX A2L ;Get Length (Pages) [from Monitor]
D619: A5 01 RAMTEST4 LDA NDATA ;Get Inverted Test NDATA ($FF|$00)
D61B: 91 0A STA (R5L),Y ;Store (NDATA) in each Byte of Test Block
; ------------------------- ;Setup Gallop Bit Mask (Aux-Register #6):
D61D: 84 0D STY R6H ;Set Bit Mask, High = Byte Ptr [0..255]
D61F: 84 0C STY R6L ;Set Bit Mask, Low = Byte Ptr [0..255]
D621: E6 0C INC R6L ;Advance Gallop Bit Mask, Low [1..256|0]
; ----------------------------------- ;Gallop Through Memory Bytes [Test Loop]:
D623: A5 01 RAMTEST5 LDA NDATA ;Retrieve Inverted Test NDATA ($FF|$00)
D625: 20 45 D6 JSR RAMTEST6 ;Gallop with Inverted Test NDATA
D628: A5 00 LDA DATA ;Retrieve [Normal] Test DATA ($00|$FF)
D62A: 20 45 D6 JSR RAMTEST6 ;Gallop with [Normal] Test DATA
; ------------------------- ;Shift Gallop Bit Mask (Aux-Register #6)
; ;to Test Next Neighbor Bit:
D62D: 06 0C ASL R6L ;Shift Gallop Test Bit Mask, Low
D62F: 26 0D ROL R6H ;Shift Gallop Test Bit Mask, High
D631: A5 0D LDA R6H ;Retrieve Gallop Test Bit Mask, High
D633: C5 3E CMP A2L ;Is Bit-Mask > Length? (Pages)
D635: 90 EC BCC RAMTEST5 ;NO, Loop if Not Done
D637: A5 00 LDA DATA ;YES, Done; Retrieve Test DATA ($00|$FF)
D639: 91 0A STA (R5L),Y ;Restore Memory Test Byte
D63B: E6 0A INC R5L ;Advance Memory Byte Pointer
D63D: D0 DA BNE RAMTEST4 ;Loop until 256 Bytes have been Tested
D63F: E6 0B INC R5H ;Advance Memory Page Pointer
D641: CA DEX ;Reduce Page Counter (Length)
D642: D0 D5 BNE RAMTEST4 ;Loop until all Pages are Done
D644: 60 RT_RTS1 RTS ;Return to Caller
; ----------------------------------- ;Gallop Through Memory Bytes [Test S/R]:
D645: 85 02 RAMTEST6 STA TESTD ;Save Gallop TEST Data
; ------------------------- ;Set Pointer (Aux-Register #4)
; ;for Neighbor Address (1-Bit Difference):
D647: A5 0A LDA R5L ;Get Memory Byte Pointer
D649: 45 0C EOR R6L ;Set (A)=(R5L XOR R6L)
D64B: 85 08 STA R4L ;Set Pointer (Aux-Register #4, Low)
D64D: A5 0B LDA R5H ;Get Memory Page Pointer
D64F: 45 0D EOR R6H ;Set (A)=(R5H XOR R6H)
D651: 85 09 STA R4H ;Set Pointer (Aux-Register #4, High)
; ------------------------- ;Test Memory Test Bytes for Changes
; ;when Neighboring Address Bytes are Set:
D653: A5 02 LDA TESTD ;Retrieve Gallop TEST Data
D655: 91 08 STA (R4L),Y ;Set Neighbor Memory Byte = TEST Data
D657: B1 0A LDA (R5L),Y ;Retrieve Memory Test Byte (Different Ptr)
D659: C5 01 CMP NDATA ;Check for a Change: is (A)=(NDATA)?
D65B: F0 E7 BEQ RT_RTS1 ;Return to Caller if OK: (A)=(NDATA)
; ----------------------------------- ;Else, Test Byte is Changed; Handle Error:
D65D: 48 PHA ;Preserve Bad (Memory Failure) Data
D65E: A5 0B LDA R5H ;Get Memory Test Page Pointer
D660: 20 DA FD JSR PRBYTE ;Print A-Reg as Two-Digit Hex Number
D663: A5 0A LDA R5L ;Get Memory Test Byte Pointer
D665: 20 8A D6 JSR RTPRBYSP ;Print (A):[as Two-Digit Hex #] & a Space
D668: A5 01 LDA NDATA ;Retrieve Inverted Test NDATA ($FF|$00)
D66A: 91 0A STA (R5L),Y ;Replace/Correct Bad Memory with NDATA
D66C: 20 8A D6 JSR RTPRBYSP ;Print (A):[as Two-Digit Hex #] & a Space
D66F: 68 PLA ;Retrieve Bad (Memory Failure) Data
; ------------------------------------------------------------------------------
; ** This jump causes a crash into the Monitor unless there is code at $02CB! **
; ** There is info about this out in Cyberspace, but I have not found it yet! **
; ------------------------------------------------------------------------------
D670: 4C CB 02 JMP INBUFF+203 ;Go to User Routine near End of Input Page
; ------------------------------------------------------------------------------
; The line above is code from an actual PA1 ROM. It is changed from that in
; the "Programmer's Aid #1 Installation and Operating Manual" "RAMTEST" listing
; (pages 84~86). [$D670:4CCB02 JMP $02CB versus 208AD6 JSR $D68A, respectively]
; ------------------------------------------------------------------------------
; [versus] JSR RTPRBYSP ;Print (A):[as Two-Digit Hex #] & a Space
; ------------------------------------------------------------------------------
; ** The following cannot happen unless the User Routine jumps back to $D673! **
; ------------------------------------------------------------------------------
;
; ----------------------------------- ;Continue/Finish Handling Error:
D673: A5 09 RTERRFIN LDA R4H ;Get Neighbor Memory Test Page Pointer
D675: 20 DA FD JSR PRBYTE ;Print A-Reg as Two-Digit Hex Number
D678: A5 08 LDA R4L ;Get Neighbor Memory Test Byte Pointer
D67A: 20 8A D6 JSR RTPRBYSP ;Print (A):[as Two-Digit Hex #] & a Space
D67D: A5 02 LDA TESTD ;Retrieve Gallop TEST Data
;
; ------------------------------------------------------------------------------
; The following subroutine was used as such (see "[versus]" above at $D60C) in
; the "Programmer's Aid #1 Installation and Operating Manual" "RAMTEST" listing
; (pages 84~86). Now, in PA1 ROMs, it is not used as a separate subroutine.
; ------------------------------------------------------------------------------
;
; ----------------------------------- ;Print (A):[##], Error + Beep, Space + CR:
D67F: 20 8A D6 RTPRBYCR JSR RTPRBYSP ;Print (A):[as Two-Digit Hex #] & a Space
D682: 20 2D FF JSR PRERR ;Print "ERR" & Sound Bell
;
; ------------------------------------------------------------------------------
; ** (End of what cannot happen unless the User Routine jumps back to $D673!) **
; ------------------------------------------------------------------------------
;
D685: A9 8D RTCROUT LDA #$8D ;Get a Carriage Return (Ctrl-M) Character
D687: 4C ED FD JMP COUT ;Print A-Reg; Returns to Caller
;
; ----------------------------------- ;Print (A):[as Two-Digit Hex #] & a Space
D68A: 20 DA FD RTPRBYSP JSR PRBYTE ;Print A-Reg as Two-Digit Hex Number
D68D: A9 A0 LDA #' ' | $80 ;Get a Blank|Space Character
D68F: 4C ED FD JMP COUT ;Print A-Reg; Returns to Caller
; ==============================================================================
; *v* (End of "RAMTEST" listing in the "Installation and Operating Manual"!) *v*
; ==============================================================================
; 03F8:4C C3 D5 USRADR JMP RAMTEST ;Entry from Monitor (Ctrl-Y) <-[Renamed]
; ------------------------------------------------------------------------------
;
;
; ==============================================================================
; Print Bad Memory Chip's Row & Column Location on Apple II Moterboards:
; ==============================================================================
; *v* (Not in "RAMTEST" listing in the "Installation and Operating Manual"!) *v*
; ------------------------------------------------------------------------------
;
; ----------------------------------- ;Flag Bad Bits in Bad Memory Byte:
D692: 84 0F RTBADMEM STY R7H ;Save Byte Pointer [0..255]
D694: 85 0E STA R7L ;Save Bad (Memory Failure) Data
D696: 20 8A D6 JSR RTPRBYSP ;Print (A):[as Two-Digit Hex #] & a Space
D699: 20 2D FF JSR PRERR ;Print "ERR" & Sound Bell
D69C: A5 00 LDA DATA ;Get [Normal] Test DATA ($00|$FF)
D69E: 45 0E EOR R7L ;Compute [(Test DATA) XOR (Bad DATA)]
D6A0: 85 0E STA R7L ;Save XOR Result = Bad Bits in Memory Byte
; ----------------------------------- ;Determine Chip's Motherboard Location:
D6A2: A0 07 LDY #7 ;Init Loop Counter (for 8 Iterations)
D6A4: 46 0E RTLOCLOOP LSR R7L ;Is Current Least Significant Bit Set?
D6A6: 90 23 BCC RTLOCNEXT ;Branch if Not a Bad Bit in Memory Byte
; ----------------------------------- ;Else, there is a Bad Bit in Memory Byte;
; ;Print Chip's (Row/Column) Location:
D6A8: A9 A0 LDA #' ' | $80 ;Get a Blank/Space Character
D6AA: 20 ED FD JSR COUT ;Print A-Reg to Output Device
D6AD: A5 3D LDA A1H ;Get Start of Test Block Address, High
D6AF: C9 50 CMP #$50 ;Set Carry if [(A)>=(80)]
D6B1: A9 C4 LDA #'D' | $80 ;Get a 'D' Character
D6B3: 69 00 ADC #0 ;Add Carry from Comparison
D6B5: 20 ED FD JSR COUT ;Print Motherboard Row [(A)=('D'|'E')]
; ;^[How does this print 'C' (for Row 'C')?]
D6B8: A9 AD LDA #'-' | $80 ;Get a Dash Character
D6BA: 20 ED FD JSR COUT ;Print A-Reg to Output Device
D6BD: 98 TYA ;Get Loop Counter: (Y)=(7,6,5,4,3,2,1,0)=
; ;^[(Y)=(Index to get Motherboard Column)]
D6BE: D0 05 BNE RTLOCPRDN ;Skip prefixing '1' character when (Y>0)
D6C0: A9 B1 LDA #'1' | $80 ;Get a '1' char to print '10' when (Y=0)
D6C2: 20 ED FD JSR COUT ;Print A-Reg to Output Device
D6C5: B9 D3 D6 RTLOCPRDN LDA DECNUMS,Y ;Get Decimal Number (Motherboard Column)=
; ;^[(A)=(3,4,5,6,7,8,9,0):(0 is column 10)]
D6C8: 20 ED FD JSR COUT ;Print A-Reg to Output Device
D6CB: 88 RTLOCNEXT DEY ;Reduce Loop Counter
D6CC: 10 D6 BPL RTLOCLOOP ;Loop until [(Y)=(-1)]
D6CE: A4 0F LDY R7H ;Retrieve Byte Pointer [0..255]
D6D0: 4C 85 D6 JMP RTCROUT ;Print Carriage Return; Returns to Caller
; ------------------------------------------------------------------------------
; Decimal Numbers Table: For RAM Chip Columns on A2 Motherboards
; ------------------------------------------------------------------------------
; [RAM Chip Rows = (C|D|E), Columns = (3,4,5,6,7,8,9,10)]
;
; ----------------------------------- ;RAM Chip Columns:
D6D3: B0 DECNUMS DFB '0' | $80 ;RAM Chip Column 10
D6D4: B9 DFB '9' | $80 ;RAM Chip Column 9
D6D5: B8 DFB '8' | $80 ;RAM Chip Column 8
D6D6: B7 DFB '7' | $80 ;RAM Chip Column 7
D6D7: B6 DFB '6' | $80 ;RAM Chip Column 6
D6D8: B5 DFB '5' | $80 ;RAM Chip Column 5
D6D9: B4 DFB '4' | $80 ;RAM Chip Column 4
D6DA: B3 DFB '3' | $80 ;RAM Chip Column 3
D6DB: B2 DFB '2' | $80 ;Not a RAM Chip Column
D6DC: B1 DFB '1' | $80 ;Not a RAM Chip Column
;
; ==============================================================================
; Apple II [$D0 ROM] (341-0016) - Programmer's Aid #1 [1978]
; ==============================================================================
; Part 2.5 [$D692~$D716]: BASIC Entry Points by Steve Wozniak [WOZ];
; Copyright (c) 1978 by Apple Computer Inc. All Rights Reserved
; ------------------------------------------------------------------------------
; Instructions are in the Programmer's Aid #1 Installation and Operating Manual
; ==============================================================================
; Analyzed (via McFadden's SourceGen) by James Davis [Last Updated: 2020-07-10]
; ==============================================================================
;
;
; ==============================================================================
; Renumber/Append Sweet 16 Equates: SW16 Registers & Locations used here ... (*)
; ==============================================================================
; NEWINCR EQU $02 {addr/1} ;R1L: New LNO Increment (INCR) Value (*)
; LNLO EQU $03 {addr/1} ;R1H: Low LNO of RENUM Range (*)
; LNHI EQU $04 {addr/1} ;R2L: High LNO of RENUM Range (*)
; TBLSTRT EQU $05 {addr/1} ;R2H: LNO Table Start (*)
; TBLINDX1 EQU $06 {addr/1} ;R3L: Pass 1 LNO Table Index (*)
; TBLIM EQU $07 {addr/1} ;R3H: LNO Table Limit (*)
; SCR8 EQU $08 {addr/1} ;R4L: Scratch Register (*)
; HMEM EQU $08 {addr/1} ;R4L: HIMEM (End of Program) (*)
; SCR9 EQU $09 {addr/1} ;R4H: Scratch Register (*)
; PRGNDX EQU $09 {addr/1} ;R4H: Pass 1 Program Index (*)
; ==============================================================================
;
;
; ==============================================================================
; BASIC Renumber Subroutine Entry Points:
; ==============================================================================
;
; ****************************************
; * *
; * RENUMBER *
; * >CLR *
; * >START= *
; * >STEP= *
; * >CALL -10531 *
; * =($D6DD) *
; * *
; * OPTIONAL *
; * >FROM= *
; * >TO= *
; * >CALL -10521 *
; * =($D6E7) *
; * *
; * USE RENX ENTRY *
; * FOR RENUMBER ALL *
; * *
; ****************************************
;
; ----------------------------------- ;BASIC Renumber S/R Entry Pt.: Call -10531
; ;(to renumber an entire BASIC program)
D6DD: A0 00 RENALL LDY #0 ;Clear Y-Index Register
D6DF: 84 06 STY R3L ;Clear Sweet 16 Register #3, Low
D6E1: 84 07 STY R3H ;Clear Sweet 16 Register #3, High
D6E3: 88 DEY ;Reduce Y-Index to -1
D6E4: 98 TYA ;Set Accumulator to -1
D6E5: D0 0E BNE RENCOMMON ;Always Taken
;
; ----------------------------------- ;BASIC Renumber S/R Entry Pt.: Call -10521
; ;(to renumber part of a BASIC program)
D6E7: A0 1A RENPART LDY #26 ;Set Indexed Addressing Index
D6E9: 20 0E D7 JSR RENGETVAR ;Set (A,Y)=(BASIC VARTAB Entry, Lo/Hi)
D6EC: 85 06 STA R3L ;Set Sweet 16 Register #3, Low
D6EE: 84 07 STY R3H ;Set Sweet 16 Register #3, High
D6F0: A0 21 LDY #33 ;Set Indexed Addressing Index
D6F2: 20 0E D7 JSR RENGETVAR ;Set (A,Y)=(BASIC VARTAB Entry, Lo/Hi)
;
; ----------------------------------- ;BASIC Renumber Entry Pts. Common Routine:
; ;(to renumber all or part of a program)
D6F5: 85 08 RENCOMMON STA R4L ;Set Sweet 16 Register #4, Low
D6F7: 84 09 STY R4H ;Set Sweet 16 Register #4, High
D6F9: A0 08 LDY #8 ;Set Indexed Addressing Index
D6FB: 20 0E D7 JSR RENGETVAR ;Set (A,Y)=(BASIC VARTAB Entry, Lo/Hi)
D6FE: 85 02 STA R1L ;Set Sweet 16 Register #1, Low
D700: 84 03 STY R1H ;Set Sweet 16 Register #1, High
D702: A0 11 LDY #17 ;Set Indexed Addressing Index
D704: 20 0E D7 JSR RENGETVAR ;Set (A,Y)=(BASIC VARTAB Entry, Lo/Hi)
D707: 85 04 STA R2L ;Set Sweet 16 Register #2, Low
D709: 84 05 STY R2H ;Set Sweet 16 Register #2, High
D70B: 4C 08 D4 JMP RENUM ;Go to Apple II BASIC Renumber Subroutine
; ==============================================================================
; Renumber/Append Get BASIC Variable Table Entry Subroutine
; ==============================================================================
;
; ----------------------------------- ;Set (A,Y)=(BASIC VARTAB Entry, Lo/Hi)
D70E: B1 4A RENGETVAR LDA (LOMEM),Y ;Get BASIC Variable Table Entry, Low
D710: 48 PHA ;Push BASIC Variable Table Entry, Low
D711: C8 INY ;Advance Indexed Addressing Index
D712: B1 4A LDA (LOMEM),Y ;Get BASIC Variable Table Entry, High
D714: A8 TAY ;Set (Y)=(BASIC VARTAB Entry, High)
D715: 68 PLA ;Set (A)=(BASIC VARTAB Entry, Low)
D716: 60 RTS ;Return to Caller
;
; ==============================================================================
; Apple II [$D0 ROM] (341-0016) - Programmer's Aid #1 [1978]
; ------------------------------------------------------------------------------
; Part 6 [$D717~$D7FF]: Music Subroutine by Gary J. Shannon;
; Copyright (c) 1978 by Apple Computer Inc. All Rights Reserved
; ------------------------------------------------------------------------------
; Instructions are in the Programmer's Aid #1 Installation and Operating Manual
; ==============================================================================
; Analyzed (via McFadden's SourceGen) by James Davis [Last Updated: 2020-07-10]
; ==============================================================================
;
; ==============================================================================
; Music Subroutine by Gary J. Shannon [Do Pokes, then Call -10473 from BASIC]
; ==============================================================================
; DURATION EQU $02 ;Renamed to match Instructions; Original Name: LENGTH
; TIMBRE EQU $02FD ;Renamed to match Instructions; Original Name: VOICE
; TIME EQU $02FE ;Renamed to match Instructions; Original Name: LONG
; PITCH EQU $02FF ;Renamed to match Instructions; Original Name: NOTE
; ------------------------------------------------------------------------------
;
D717: 4C 4E D7 ENTRY JMP LOOKUP ;Get Pulse Widths (Duty Cycle Data)
; ------------------------------------------------------------------------------
; Play One Note: Musical Note Cycles are divided into UPTIME & DOWNTIME halves;
; Musical Note Duty Cycle Data is from NOTES: UPTIME & DOWNTIME;
; Musical Note Time-Duration Count is kept in DURATION
; ------------------------------------------------------------------------------
;
; ----------------------------------- ;UPTIME Half-Cycle:
D71A: A4 01 PLAY1 LDY UPTIME ;Get Positive Pulse Width
D71C: AD 30 C0 LDA SPEAKER ;Toggle Speaker Data Output
D71F: E6 02 PLAY2 INC DURATION ;Advance Note Time-Duration Counter, Low
D721: D0 05 BNE PATH1 ;Branch if Duration (Low) is Not Expired
D723: E6 03 INC DURATION+1 ;Advance Note Time-Duration Counter, High
D725: D0 05 BNE PATH2 ;Branch if Duration (High) is Not Expired
D727: 60 RTS ;Return to Caller; Time-Duration Expired
; ;Do Time Adjustments:
D728: EA PATH1 NOP ;Delay (2 Machine Cycles)
D729: 4C 2C D7 JMP PATH2 ;Delay (3 Machine Cycles) More
D72C: 88 PATH2 DEY ;Reduce Pulse Counter (Width)
D72D: F0 05 BEQ PLAY0 ;Toggle if Pulse Count (Width) is Expired
D72F: 4C 32 D7 JMP PATH3 ;Continue UPTIME if Count is Not Expired
; ;Jump Delays (3 Machine Cycles) More
D732: D0 EB PATH3 BNE PLAY2 ;UPTIME: Same # of Cyles; Always Taken
; ----------------------------------- ;DOWNTIME Half-Cycle:
D734: A4 00 PLAY0 LDY DOWNTIME ;Get Negative Pulse Width
D736: AD 30 C0 LDA SPEAKER ;Toggle Speaker Data Output
D739: E6 02 PLAY3 INC DURATION ;Advance Note Time-Duration Counter, Low
D73B: D0 05 BNE PATH4 ;Branch if Duration (Low) is Not Expired
D73D: E6 03 INC DURATION+1 ;Advance Note Time-Duration Counter, High
D73F: D0 05 BNE PATH5 ;Branch if Duration (High) is Not Expired
D741: 60 RTS ;Return to Caller; Time-Duration Expired
; ;Do Time Adjustments:
D742: EA PATH4 NOP ;Delay (2 Machine Cycles)
D743: 4C 46 D7 JMP PATH5 ;Delay (3 Machine Cycles) More
D746: 88 PATH5 DEY ;Reduce Pulse Counter (Width)
D747: F0 D1 BEQ PLAY1 ;Toggle if Pulse Count (Width) is Expired
D749: 4C 4C D7 JMP PATH6 ;Continue DOWNTIME if Count is Not Expired
; ;Jump Delays (3 Machine Cycles) More
D74C: D0 EB PATH6 BNE PLAY3 ;DOWNTIME: Same # of Cyles; Always Taken
; ------------------------------------------------------------------------------
; Note Table Lookup Subroutine: Gets a Note's UPTIME & DOWNTIME from its PITCH &
; Sets its DURATION in accordance with its TIMBRE
; ------------------------------------------------------------------------------
; DURATION EQU $02 ;Musical Note Time-Duration Counter
; TIMBRE EQU $02FD ;Musical Note Timbre Value (Poke 765)
; TIME EQU $02FE ;Musical Note Time Value (Poke 766)
; PITCH EQU $02FF ;Musical Note Pitch Value (Poke 767)
; ------------------------------------------------------------------------------
D74E: AD FF 02 LOOKUP LDA PITCH ;Get Musical Note Pitch Value (User Poked)
D751: 0A ASL A ;Double Musical Note Pitch Value (1 of 2)
D752: A8 TAY ;Set Indexed Addressing Pointer
D753: B9 96 D7 LDA NOTES,Y ;Get Note UPTIME (Positive Pulse Width)=
D756: 85 00 STA DOWNTIME ;Set Note DOWNTIME (Negative Pulse Width)=
; ----------------------------------- ;Shift Time According to Note's TIMBRE:
D758: AD FD 02 LDA TIMBRE ;Get Note's Timbre Value (User Poked)
D75B: 4A SHIFT LSR A ;Halve Note Timbre Value (Duty Cycle)
D75C: F0 04 BEQ DONE ;Exit if Halving Results in a Zero Value
D75E: 46 00 LSR DOWNTIME ;Else, Halve Negative Pulse Width, too
D760: D0 F9 BNE SHIFT ;Loop if Halving Result is Not Zero yet
; ----------------------------------- ;Compute New UPTIME/DOWNTIME Pulse Widths:
D762: B9 96 D7 DONE LDA NOTES,Y ;Get Original Note's Positive Pulse Width
; ;Compute Difference:
D765: 38 SEC ;Prep to Subtract w/o Borrow [A-Data-!C]
D766: E5 00 SBC DOWNTIME ;Subtract Shifted Negative Pulse Width
D768: 85 01 STA UPTIME ;*** Set New Positive Pulse Width ***
D76A: C8 INY ;Advance Indexed Addressing Pointer
D76B: B9 96 D7 LDA NOTES,Y ;Get Original Note's Negative Pulse Width
; ;Add Difference [Add w/ Carry: A+Data+C]:
D76E: 65 00 ADC DOWNTIME ;Add Shifted Negative Pulse Width
D770: 85 00 STA DOWNTIME ;*** Set New Negative Pulse Width ***
; ----------------------------------- ;Compute Compliment of Duration Count:
D772: A9 00 LDA #0 ;Prepare to Subtract from Zero
D774: 38 SEC ;Prep to Subtract w/o Borrow [A-Data-!C]
D775: ED FE 02 SBC TIME ;Subtract Musical Note Time Value
D778: 85 03 STA DURATION+1 ;Set Note Time-Duration Counter, High
D77A: A9 00 LDA #0 ;Clear Accumulator
D77C: 85 02 STA DURATION ;Set Note Time-Duration Counter, Low
; ----------------------------------- ;Prepare to Play Musical Note:
D77E: A5 01 LDA UPTIME ;Get Positive Pulse Width
D780: D0 98 BNE PLAY1 ;If Note is Not a Rest Note, Play it ...
;
; ------------------------------------------------------------------------------
; Rest Note Subroutine: Plays Note #0 Silently, with same/regular Note Durations
; ------------------------------------------------------------------------------
;
; Rest Note Iterations: Do UPTIME 1st, DOWNTIME 2nd; == Same # of UP/DOWN Cyles
;
; ;Do Time Adjustments:
D782: EA REST NOP ;Delay (2 Machine Cycles)
D783: EA NOP ;Delay (2 Machine Cycles) More
D784: 4C 87 D7 JMP REST2 ;Delay (3 Machine Cycles) More
D787: E6 02 REST2 INC DURATION ;Advance Note Time-Duration Counter, Low
D789: D0 05 BNE REST3 ;Branch if Duration (Low) is Not Expired
D78B: E6 03 INC DURATION+1 ;Advance Note Time-Duration Counter, High
D78D: D0 05 BNE REST4 ;Branch if Duration (High) is Not Expired
D78F: 60 RTS ;Return to Caller; Time-Duration Expired
D790: EA REST3 NOP ;Delay (2 Machine Cycles)
D791: 4C 94 D7 JMP REST4 ;Delay (3 Machine Cycles) More
D794: D0 EC REST4 BNE REST ;Do DOWNTIME: Same Cyle; Always Taken
; ------------------------------------------------------------------------------
; Notes Table: Values are in UP/DOWN Pairs; e.g., 1st Note is a Rest [#0 =(0,0)]
; ------------------------------------------------------------------------------
;
D796: 00 00 NOTES HEX 0000 ;Note #00: A Rest (A Silence, Not a Pitch)
; Chromatic Octave: "Contra" [Below Bass Clef] - [Low End of Partial Octave]
D798: F6 F6 HEX F6F6 ;Note #01: Contra F or (uppercase) FF
D79A: E8 E8 HEX E8E8 ;Note #02: Contra F# (F-sharp or G-flat)
D79C: DB DB HEX DBDB ;Note #03: Contra G or (uppercase) GG
D79E: CF CF HEX CFCF ;Note #04: Contra G# (G-sharp or A-flat)
D7A0: C3 C3 HEX C3C3 ;Note #05: Contra A or (uppercase) AA
D7A2: B8 B8 HEX B8B8 ;Note #06: Contra A# (A-sharp or B-flat)
D7A4: AE AE HEX AEAE ;Note #07: Contra B or (uppercase) BB
; Chromatic Octave: "Great" [Bottom of & below Bass Clef]
D7A6: A4 A4 HEX A4A4 ;Note #08: Great C or (uppercase) C
D7A8: 9B 9B HEX 9B9B ;Note #09: Great C# (C-sharp or D-flat)
D7AA: 92 92 HEX 9292 ;Note #10: Great D or (uppercase) D
D7AC: 8A 8A HEX 8A8A ;Note #11: Great D# (D-sharp or E-flat)
D7AE: 82 82 HEX 8282 ;Note #12: Great E or (uppercase) E
D7B0: 7B 7B HEX 7B7B ;Note #13: Great F or (uppercase) F
D7B2: 74 74 HEX 7474 ;Note #14: Great F# (F-sharp or G-flat)
D7B4: 6D 6E HEX 6D6E ;Note #15: Great G or (uppercase) G
D7B6: 67 68 HEX 6768 ;Note #16: Great G# (G-sharp or A-flat)
D7B8: 61 62 HEX 6162 ;Note #17: Great A or (uppercase) A
D7BA: 5C 5C HEX 5C5C ;Note #18: Great A# (A-sharp or B-flat)
D7BC: 57 57 HEX 5757 ;Note #19: Great B or (uppercase) B
; Chromatic Octave: "Small" [Top of Bass Clef] (letters may be lowercase)
D7BE: 52 52 HEX 5252 ;Note #20: Small C or (lowercase) c
D7C0: 4D 4E HEX 4D4E ;Note #21: Small C# (C-sharp or D-flat)
D7C2: 49 49 HEX 4949 ;Note #22: Small D or (lowercase) d
D7C4: 45 45 HEX 4545 ;Note #23: Small D# (D-sharp or E-flat)
D7C6: 41 41 HEX 4141 ;Note #24: Small E or (lowercase) e
D7C8: 3D 3E HEX 3D3E ;Note #25: Small F or (lowercase) f
D7CA: 3A 3A HEX 3A3A ;Note #26: Small F# (F-sharp or G-flat)
D7CC: 36 37 HEX 3637 ;Note #27: Small G or (lowercase) g
D7CE: 33 34 HEX 3334 ;Note #28: Small G# (G-sharp or A-flat)
D7D0: 30 31 HEX 3031 ;Note #29: Small A or (lowercase) a
D7D2: 2E 2E HEX 2E2E ;Note #30: Small A# (A-sharp or B-flat)
D7D4: 2B 2C HEX 2B2C ;Note #31: Small B or (lowercase) b
; Chromatic Octave: "One-Line" [Most of Treble Clef] (letters may be lowercase)
D7D6: 29 29 HEX 2929 ;Note #32: One-line C, C-one, or C^1
; ;^[Middle C is half-way between the Clefs]
D7D8: 26 27 HEX 2627 ;Note #33: One-line C# (C-sharp or D-flat)
D7DA: 24 25 HEX 2425 ;Note #34: One-line D, D-one, or D^1
D7DC: 22 23 HEX 2223 ;Note #35: One-line D# (D-sharp or E-flat)
D7DE: 20 21 HEX 2021 ;Note #36: One-line E, E-one, or E^1
D7E0: 1E 1F HEX 1E1F ;Note #37: One-line F, F-one, or F^1
D7E2: 1D 1D HEX 1D1D ;Note #38: One-line F# (F-sharp or G-flat)
D7E4: 1B 1C HEX 1B1C ;Note #39: One-line G, G-one, or G^1
D7E6: 1A 1A HEX 1A1A ;Note #40: One-line G# (G-sharp or A-flat)
D7E8: 18 19 HEX 1819 ;Note #41: One-line A, A-one, or A^1
D7EA: 17 17 HEX 1717 ;Note #42: One-line A# (A-sharp or B-flat)
D7EC: 15 16 HEX 1516 ;Note #43: One-line B, B-one, or B^1
; Chromatic Octave: "Two-Line" [Top of & above Treble Clef] (may be lowercase)
D7EE: 14 15 HEX 1415 ;Note #43: Two-line C, C-two, or C^2
D7F0: 13 14 HEX 1314 ;Note #33: Two-line C# (C-sharp or D-flat)
D7F2: 12 12 HEX 1212 ;Note #46: Two-line D, D-two, or D^2
D7F4: 11 11 HEX 1111 ;Note #47: Two-line D# (D-sharp or E-flat)
D7F6: 10 10 HEX 1010 ;Note #48: Two-line E, E-two, or E^2
D7F8: 0F 10 HEX 0F10 ;Note #49: Two-line F, F-two, or F^2
D7FA: 0E 0F HEX 0E0F ;Note #50: Two-line F# (F-sharp or G-flat)
; ----------------------------------- ;^[High End of Partial Octave]
D7FC: FF FF HEX FFFF ;Junk Bytes
D7FE: FF FF HEX FFFF ;Junk Bytes